[FEATURE] Implement kernel -> user connection 21/15621/4
authorAlexander Aksenov <a.aksenov@samsung.com>
Thu, 23 Jan 2014 12:04:02 +0000 (16:04 +0400)
committerAlexander Aksenov <a.aksenov@samsung.com>
Thu, 27 Feb 2014 08:29:39 +0000 (12:29 +0400)
Based on netlink

Change-Id: If2de08afc34d01c1616155770e3236d9adc3fefd
Signed-off-by: Alexander Aksenov <a.aksenov@samsung.com>
daemon/daemon.c
daemon/daemon.h
daemon/main.c
daemon/us_interaction_msg.h [new file with mode: 0644]

index f84feb2d7b744342a0c5073f35cc5fcada8322a2..ae53677220e86e914e7a839b6a400377a78d03fc 100644 (file)
@@ -43,6 +43,8 @@
 #include <sys/timerfd.h>       // for timerfd
 #include <unistd.h>            // for access, sleep
 #include <stdbool.h>
+#include <linux/netlink.h>
+#include <linux/connector.h>
 
 #include <ctype.h>
 
@@ -60,6 +62,7 @@
 #include "da_data.h"
 #include "input_events.h"
 #include "smack.h"
+#include "us_interaction_msg.h"
 #include "debug.h"
 
 #define DA_WORK_DIR                    "/home/developer/sdk_tools/da/"
@@ -820,8 +823,57 @@ static int hostServerHandler(void)
        }
 }
 
+static int kernel_handler(void)
+{
+       int res, size, ret;
+       socklen_t optlen;
+       struct nlmsghdr *nlh;
+       struct cn_msg *msg;
+       ssize_t len;
+
+       /* Get buffer size */
+       optlen = sizeof(size);
+
+       /* We're using SOCK_DGRAM, so, get it maximum size */
+       res = getsockopt(manager.kernel_socket, SOL_SOCKET, SO_SNDBUF, &size,
+                        &optlen);
+
+       if (res == -1) {
+               LOGE("Get maximum buffer size failed\n");
+               return -1;
+       }
+
+       /* Alloc mem for nlh message struct and receive it */
+       nlh = malloc(size);
+       if (nlh == NULL)
+               return -1;
+       len = recv(manager.kernel_socket, nlh, size, 0);
+       if ((len <= 0) || (nlh->nlmsg_len == 0)) {
+               ret = -1;
+               goto free_and_end;
+       }
+
+       /* nlh data field contains connectors message */
+       msg = NLMSG_DATA(nlh);
+       if (msg->len == 0) {
+               ret = -1;
+               goto free_and_end;
+       }
+
+       /* Insert your message handler here */
+
+       ret = 0;
+
+free_and_end:
+       free(nlh);
+
+       return ret;
+}
+
+
 static Ecore_Fd_Handler *host_connect_handler;
 static Ecore_Fd_Handler *target_connect_handler;
+static Ecore_Fd_Handler *kernel_connect_handler;
 
 static Eina_Bool host_connect_cb(void *data, Ecore_Fd_Handler *fd_handler)
 {
@@ -846,6 +898,15 @@ static Eina_Bool target_connect_cb(void *data, Ecore_Fd_Handler *fd_handler)
        return ECORE_CALLBACK_RENEW;
 }
 
+static Eina_Bool kernel_connect_cb(void *data, Ecore_Fd_Handler *fd_handler)
+{
+       if (kernel_handler() < 0) {
+               LOGE("Internal DA framework error (kernel_handler)\n");
+       }
+
+       return ECORE_CALLBACK_RENEW;
+}
+
 static bool initialize_events(void)
 {
        host_connect_handler =
@@ -870,6 +931,17 @@ static bool initialize_events(void)
                return false;
        }
 
+       kernel_connect_handler =
+           ecore_main_fd_handler_add(manager.kernel_socket,
+                                     ECORE_FD_READ,
+                                     kernel_connect_cb,
+                                     NULL,
+                                     NULL, NULL);
+       if (!kernel_connect_handler) {
+               LOGE("Kernel socket add error\n");
+               return false;
+       }
+
        return true;
 }
 
index 40441c25e5b5e485e5071813c656aa5471a0e099..5d7c74de293bb3d136154e333d817abd0b93547f 100644 (file)
@@ -172,6 +172,7 @@ typedef struct
 {
        int host_server_socket;
        int target_server_socket;
+       int kernel_socket;
        int target_count;
        int apps_to_run;
        unsigned int config_flag;
index a3048379848b028b4082553a94dd94f45d50a725..519c3a283edac3b345c809d86349a833f9e6114b 100644 (file)
@@ -37,6 +37,8 @@
 #include <sys/socket.h>                // for socket
 #include <sys/un.h>                    // for sockaddr_un
 #include <arpa/inet.h>         // for sockaddr_in, socklen_t
+#include <linux/netlink.h>
+#include <linux/connector.h>
 
 #include <signal.h>                    // for signal
 #include <unistd.h>                    // for unlink
@@ -50,6 +52,7 @@
 #include "debug.h"
 #include "utils.h"
 #include "smack.h"
+#include "us_interaction_msg.h"
 
 #define SINGLETON_LOCKFILE                     "/tmp/da_manager.lock"
 #define PORTFILE                                       "/tmp/port.da"
@@ -64,6 +67,7 @@ __da_manager manager =
 {
        .host_server_socket = -1,
        .target_server_socket = -1,
+       .kernel_socket = -1,
        .target_count = 0,
        .apps_to_run = 0,
        .config_flag = 0,
@@ -118,6 +122,8 @@ static void _close_server_socket(void)
                close(manager.host_server_socket);
        if(manager.target_server_socket != -1)
                close(manager.target_server_socket);
+       if (manager.kernel_socket != -1)
+               close(manager.kernel_socket);
 }
 
 static void _unlink_files(void)
@@ -236,6 +242,35 @@ static int makeHostServerSocket()
        return port;
 }
 
+// return 0 for normal case
+static int makeKernelSocket(void)
+{
+       struct sockaddr_nl nlAddr;
+       int ret;
+
+       if (manager.kernel_socket != -1)
+               return -1;      // should be never happend
+
+       manager.kernel_socket = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
+       if (manager.kernel_socket < 0) {
+               LOGE("Kernel socket creation failed\n");
+               return -1;
+       }
+
+       nlAddr.nl_family = AF_NETLINK;
+       nlAddr.nl_groups = CN_DAEMON_GROUP;
+       nlAddr.nl_pid = 0;
+
+       if (-1 == bind(manager.kernel_socket, (struct sockaddr*) &nlAddr,
+                  sizeof(nlAddr))) {
+               LOGE("Kernel socket binding failed\n");
+               return -1;
+       }
+
+       LOGI("Created KernelSock %d\n", manager.kernel_socket);
+       return 0;
+}
+
 // =============================================================================
 // initializing / finalizing functions
 // =============================================================================
@@ -310,6 +345,9 @@ static int initializeManager(FILE *portfile)
                return -1;
        }
 
+       if (makeKernelSocket() != 0)
+               return -1;
+
        int port = makeHostServerSocket();
        if (port < 0) {
                write_int(portfile, ERR_HOST_SERVER_SOCKET_CREATE_FAILED);
diff --git a/daemon/us_interaction_msg.h b/daemon/us_interaction_msg.h
new file mode 100644 (file)
index 0000000..c87a2c4
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ *  SWAP device driver
+ *  modules/driver/us_interaction_msg.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) Samsung Electronics, 2014
+ *
+ * 2014         Alexander Aksenov <a.aksenov@samsung.com>: Driver user<-> kernel
+ *                                                  connect implement
+ *
+ */
+
+#ifndef __US_INTERACTION_MSG_H__
+#define __US_INTERACTION_MSG_H__
+
+#define CN_SWAP_IDX     0x22    /* Should be unique throughout the system */
+#define CN_SWAP_VAL     0x1     /* Just the same in kernel and user */
+#define CN_DAEMON_GROUP 0x1     /* Listener group. Connector works a bit faster
+                                 * when using one */
+
+enum us_interaction_k2u_msg_t {
+       US_INT_PAUSE_APPS = 1,      /* Make daemon pause apps */
+       US_INT_CONT_APPS = 2        /* Make daemon continue apps */
+};
+
+#endif /* __US_INTERACTION_MSG_H__ */