summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnatolii Nikulin <nikulin.a@samsung.com>2016-09-08 12:50:12 +0300
committerAnatolii Nikulin <nikulin.a@samsung.com>2016-10-14 16:53:39 +0300
commit2d7bfd1ecf5a77a0ab815a05d5d2629566f1cb07 (patch)
treeb4b75ac20904f5c446271b7c639dd771059ce5ad
parent74568764618eb821cd43a9494d0011c8828cd4eb (diff)
downloadswap-manager-2d7bfd1ecf5a77a0ab815a05d5d2629566f1cb07.tar.gz
swap-manager-2d7bfd1ecf5a77a0ab815a05d5d2629566f1cb07.tar.bz2
swap-manager-2d7bfd1ecf5a77a0ab815a05d5d2629566f1cb07.zip
Rework WSI
Replace webkit by libchromium, add function to get websoket ID, update to new libwebsocket API Change-Id: I2ab20fe23fb04114a42649ba901693de8a6cd38a Signed-off-by: Anatolii Nikulin <nikulin.a@samsung.com>
-rw-r--r--daemon/Makefile2
-rw-r--r--daemon/wsi.c247
-rw-r--r--packaging/swap-manager.spec9
-rwxr-xr-xscripts/gen_wsi_prof.sh17
4 files changed, 205 insertions, 70 deletions
diff --git a/daemon/Makefile b/daemon/Makefile
index fb3e9db..c89ea11 100644
--- a/daemon/Makefile
+++ b/daemon/Makefile
@@ -190,7 +190,7 @@ endif # NSP_SUPPORT
ifeq ($(WSI_SUPPORT),y)
SRC_C += wsi.c
LDFLAGS += -lwebsockets -ljson-c
- FLAGS += -DWSI_SUPPORT
+ CFLAGS += -DWSI_SUPPORT
GENERATED_WSI_PROF_H = include/generated/wsi_prof.h
GENERATED_HEADERS += $(GENERATED_WSI_PROF_H)
diff --git a/daemon/wsi.c b/daemon/wsi.c
index 7f89fb7..e201d5d 100644
--- a/daemon/wsi.c
+++ b/daemon/wsi.c
@@ -32,6 +32,13 @@
#include <libwebsockets.h>
#include <errno.h>
#include <json.h>
+
+#include <netinet/tcp.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
#include "wsi.h"
#include "swap_debug.h"
#include "daemon.h"
@@ -40,7 +47,7 @@
#include "smack.h"
#include "wsi_prof.h" /* Generated automatically */
-#define MAX_MSG_LENGTH 4096
+#define MAX_MSG_LENGTH 8192
#define PSTATE_DEFAULT (1UL << ( 0))
#define PSTATE_CONNECTED (1UL << ( 1))
@@ -74,17 +81,15 @@ enum protocol_names {
PROTOCOL_PROFILING
};
-const char WSI_HOST[] = "127.0.0.1";
-struct libwebsocket_context *context;
-struct libwebsocket *wsi;
-
-unsigned int pstate = PSTATE_DEFAULT;
-int request_id = 1;
+static const char WSI_HOST[] = "127.0.0.1";
+static struct lws_context *__context;
+static struct lws *__wsi;
-pthread_t wsi_start_thread = -1;
-pthread_t wsi_handle_thread = -1;
+static unsigned int pstate = PSTATE_DEFAULT;
+static int request_id = 1;
-/* static void wsi_destroy(void); */
+static pthread_t wsi_start_thread = -1;
+static pthread_t wsi_handle_thread = -1;
static int set_profile_info(const char *path, const char *info)
{
@@ -111,10 +116,8 @@ int wsi_set_profile(const struct app_info_t *app_info)
{
const char INSPSERVER_START_FILE[] =
"/sys/kernel/debug/swap/webprobe/inspector_server_start";
- const char WILL_EXECUTE_FILE[] =
- "/sys/kernel/debug/swap/webprobe/will_execute";
- const char DID_EXECUTE_FILE[] =
- "/sys/kernel/debug/swap/webprobe/did_execute";
+ const char TICK_PROBE_FILE[] =
+ "/sys/kernel/debug/swap/webprobe/tick_probe";
const char APP_INFO_FILE[] =
"/sys/kernel/debug/swap/webprobe/app_info";
int ret = 0;
@@ -137,13 +140,8 @@ int wsi_set_profile(const struct app_info_t *app_info)
if (ret)
goto fail;
- snprintf(info_tmp, sizeof(info_tmp), "0x%lx", WILLEXECUTE_ADDR);
- ret = set_profile_info(WILL_EXECUTE_FILE, info_tmp);
- if (ret)
- goto fail;
-
- snprintf(info_tmp, sizeof(info_tmp), "0x%lx", DIDEXECUTE_ADDR);
- ret = set_profile_info(DID_EXECUTE_FILE, info_tmp);
+ snprintf(info_tmp, sizeof(info_tmp), "0x%lx", TICK_PROBE_ADDR);
+ ret = set_profile_info(TICK_PROBE_FILE, info_tmp);
if (ret)
goto fail;
@@ -209,7 +207,7 @@ int wsi_enable_profiling(enum web_prof_state_t mode)
return ret;
}
-static void send_request(const char *method)
+static void send_request(struct lws *wsi, const char *method)
{
#define MAX_REQUEST_LENGTH 128
@@ -244,7 +242,7 @@ static void send_request(const char *method)
strncpy(buf, payload, MAX_REQUEST_LENGTH - 1);
- if (libwebsocket_write(wsi, (unsigned char *)buf, payload_len,
+ if (lws_write(wsi, (unsigned char *)buf, payload_len,
LWS_WRITE_TEXT) < 0) {
LOGE("cannot write to web socket (method: %s)\n", method);
return;
@@ -253,21 +251,21 @@ static void send_request(const char *method)
SETSTAT(pstate, PSTATE_WAIT_ACK);
}
-static int profiling_callback(struct libwebsocket_context *context,
- struct libwebsocket *wsi,
- enum libwebsocket_callback_reasons reason,
+static int profiling_callback(struct lws *wsi,
+ enum lws_callback_reasons reason,
void *user, void *in, size_t len)
{
json_object *jobj, *jobjr;
int res_id;
+ char *msg;
switch (reason) {
case LWS_CALLBACK_CLIENT_ESTABLISHED:
LOGI("Connected to server\n");
SETSTAT(pstate, PSTATE_CONNECTED);
- send_request("Profiler.enable");
- send_request("Profiler.start");
+ send_request(wsi, "Profiler.enable");
+ send_request(wsi, "Profiler.start");
break;
case LWS_CALLBACK_DEL_POLL_FD:
@@ -280,17 +278,17 @@ static int profiling_callback(struct libwebsocket_context *context,
break;
case LWS_CALLBACK_CLIENT_RECEIVE:
- if (libwebsockets_remaining_packet_payload(wsi))
+ if (lws_remaining_packet_payload(wsi))
LOGE("json message too long\n");
- ((char *)in)[len] = '\0';
- LOGI("json message recv; len: %d; msg: %s\n", (int)len,
- (char *)in);
+ msg = in;
+ msg[len] = '\0';
+ LOGI("json message recv; len: %zu; msg: %s\n", len, msg);
- if (!libwebsocket_is_final_fragment(wsi))
+ if (!lws_is_final_fragment(wsi))
break;
- jobjr = json_tokener_parse((char *)in);
+ jobjr = json_tokener_parse(msg);
/* {"result":{},"id":?} */
json_object_object_get_ex(jobjr, "id", &jobj);
@@ -344,6 +342,9 @@ static int profiling_callback(struct libwebsocket_context *context,
*/
break;
+ case LWS_CALLBACK_GET_THREAD_ID:
+ break;
+
default:
LOGW("Message unknown. Reason: %d\n", reason);
break;
@@ -352,52 +353,67 @@ static int profiling_callback(struct libwebsocket_context *context,
return 0;
}
-static struct libwebsocket_protocols protocols[] = {
- { "profiling-protocol", profiling_callback, 0, MAX_MSG_LENGTH },
- { NULL, NULL, 0, 0 }
+static struct lws_protocols protocols[] = {
+ { "profiling-protocol", profiling_callback, 0, MAX_MSG_LENGTH, 0, NULL },
+ { NULL, NULL, 0, 0, 0, NULL }
};
-static void destroy_wsi_conn(struct libwebsocket_context *context)
+static void destroy_wsi_conn(struct lws_context *context)
{
/* */
- libwebsocket_context_destroy(context);
+ lws_context_destroy(context);
}
-static int init_wsi_conn(struct libwebsocket_context **context,
- struct libwebsocket **wsi,
- const char *address, int port)
+static inline const struct lws_extension *get_internal_extensions(void)
+{
+ return NULL;
+}
+
+#define PATH_LEN 128
+static int init_wsi_conn(struct lws_context **context, struct lws **wsi,
+ const char *address, int port, const char *id)
{
static struct lws_context_creation_info info;
+ struct lws_client_connect_info client_info;
char host[32];
char origin[32];
- const char *page = "/devtools/page/1";
+ char path[PATH_LEN];
int ietf_version = -1; /* latest */
snprintf(host, sizeof(host), "%s:%d", address, port);
snprintf(origin, sizeof(origin), "http://%s:%d", address, port);
- LOGI(" host =<%s> origin = <%s>\n", host, origin);
+ snprintf(path, sizeof(path), "/devtools/page/%s", id);
+ LOGI(" host: \"%s\", origin: \"%s\", path: \"%s\"\n",
+ host, origin, path);
memset(&info, 0, sizeof(info));
-
info.port = CONTEXT_PORT_NO_LISTEN;
info.protocols = protocols;
info.gid = -1;
info.uid = -1;
info.ssl_cert_filepath = NULL;
info.ssl_private_key_filepath = NULL;
- info.extensions = libwebsocket_get_internal_extensions();
+ info.extensions = get_internal_extensions();
info.options = 0;
- *context = libwebsocket_create_context(&info);
+ *context = lws_create_context(&info);
if (*context == NULL) {
LOGE("libwebsocket context creation failed\n");
return 1;
}
- *wsi = libwebsocket_client_connect(*context, address, port, 0, page,
- host, origin,
- protocols[PROTOCOL_PROFILING].name,
- ietf_version);
+ memset(&client_info, 0, sizeof(client_info));
+ client_info.context = *context;
+ client_info.address = address;
+ client_info.ssl_connection = 0;
+ client_info.path = path;
+ client_info.port = port;
+ client_info.host = host;
+ client_info.origin = origin;
+ client_info.protocol = protocols[PROTOCOL_PROFILING].name;
+ client_info.ietf_version_or_minus_one = ietf_version;
+
+ *wsi = lws_client_connect_via_info(&client_info);
if (*wsi == NULL) {
LOGE("libwebsocket connect failed\n");
@@ -416,17 +432,128 @@ static void *handle_ws_responses(void *arg)
!CHKSTAT(pstate, PSTATE_DISCONNECT)) ||
(!CHKSTAT(pstate, PSTATE_DISCONNECT) &&
CHKSTAT(pstate, PSTATE_INIT_DONE | PSTATE_INIT_START))) {
- libwebsocket_service(context, 1000);
+ lws_service(__context, 1000);
}
LOGI("handle response thread finished\n");
return NULL;
}
+int socket_connect(const char *host, in_port_t port)
+{
+ struct hostent *hp;
+ struct sockaddr_in addr;
+ int on = 1, sk, ret;
+
+ hp = gethostbyname(host);
+ if (!hp)
+ return -1;
+
+ memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);
+ addr.sin_port = htons(port);
+ addr.sin_family = AF_INET;
+ sk = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (sk < 0) {
+ LOGE("failed to open TCP socket\n");
+ return -1;
+ }
+
+ ret = setsockopt(sk, IPPROTO_TCP, TCP_NODELAY,
+ (const char *)&on, sizeof(int));
+
+ if (ret < 0) {
+ LOGE("failed to set socket option\n");
+ close(sk);
+ return -1;
+ }
+
+ ret = connect(sk, (struct sockaddr *)&addr,
+ sizeof(struct sockaddr_in));
+ if (ret < 0) {
+ LOGE("failed to connect socket\n");
+ close(sk);
+ return -1;
+ }
+
+ return sk;
+}
+
+#define BUFFER_SIZE 1024
+#define HTTP_REQUEST_BUFLEN 1024
+static const char __http_requst[] = "GET /json HTTP/1.1\r\n"
+ "Host: %s:%d\r\n"
+ "Connection: Keep-Alive\r\n"
+ "User-Agent: Apache-HttpClient/4.1.2 "
+ "(java 1.5)\r\n\r\n";
+static const char __http_ok[] = "HTTP/1.1 200 OK";
+static const size_t __http_ok_len = sizeof(__http_ok) - 1;
+static const char __http_end[] = "\r\n\r\n";
+static const size_t __http_end_len = sizeof(__http_end) - 1;
+
+static bool path_id_get(char *id, size_t idlen, const char *host, int port)
+{
+ bool ret = false;
+ int sk;
+ ssize_t n;
+ char buffer[BUFFER_SIZE] = { 0 };
+ char request[HTTP_REQUEST_BUFLEN];
+ size_t reqlen;
+ char *s, *p;
+ const char *id_str = NULL;
+ json_object *obj, *id_obj, *root;
+
+ sk = socket_connect(host, port);
+
+ snprintf(request, HTTP_REQUEST_BUFLEN, __http_requst, host, port);
+ reqlen = strlen(request);
+ n = write(sk, request, reqlen);
+ if (n < reqlen)
+ goto connection_shutdown;
+
+ n = read(sk, buffer, BUFFER_SIZE - 1);
+ if (n < 0)
+ goto connection_shutdown;
+
+ if (strncmp(buffer, __http_ok, __http_ok_len))
+ goto connection_shutdown;
+
+ s = buffer + __http_ok_len + 2;
+ p = strstr(s, __http_end);
+ if (!p)
+ goto connection_shutdown;
+
+ p += __http_end_len;
+ root = json_tokener_parse(p);
+ obj = json_object_array_get_idx(root, 0);
+ json_object_object_get_ex(obj, "id", &id_obj);
+ if (!id_obj)
+ goto json_root_obj_put;
+
+ id_str = json_object_get_string(id_obj);
+ if (id_str) {
+ snprintf(id, idlen, "%s", id_str);
+ ret = true;
+ } else {
+ id[0] = '\0';
+ }
+
+json_root_obj_put:
+ json_object_put(root);
+
+connection_shutdown:
+ shutdown(sk, SHUT_RDWR);
+ close(sk);
+
+ return ret;
+}
+
+#define IDLEN 128
static int wsi_init(const char *address, int port)
{
int res = 0;
int i = 0;
+ char id[IDLEN];
+
if (!port) {
char buf[sizeof(struct msg_t) + sizeof(uint32_t)];
struct msg_t *msg = (struct msg_t *)buf;
@@ -452,7 +579,13 @@ static int wsi_init(const char *address, int port)
goto exit;
}
- if (init_wsi_conn(&context, &wsi, address, port) != 0) {
+ if (!path_id_get(id, sizeof(id), address, port)) {
+ LOGE("failed to get ID for request\n");
+ res = 1;
+ goto exit;
+ }
+
+ if (init_wsi_conn(&__context, &__wsi, address, port, id) != 0) {
LOGE("cannot init wsi connection\n");
res = 1;
goto exit;
@@ -480,7 +613,7 @@ static int wsi_start_profiling(void)
{
if (pthread_create(&wsi_handle_thread, NULL, &handle_ws_responses, NULL)) {
LOGE("Can't create handle_ws_ threads\n");
- destroy_wsi_conn(context);
+ destroy_wsi_conn(__context);
return 1;
}
@@ -490,8 +623,8 @@ static int wsi_start_profiling(void)
static void wsi_stop_profiling(void)
{
if (CHKSTAT(pstate, PSTATE_CONNECTED)) {
- send_request("Profiler.stop");
- send_request("Profiler.disable");
+ send_request(__wsi, "Profiler.stop");
+ send_request(__wsi, "Profiler.disable");
}
}
@@ -575,7 +708,7 @@ void wsi_stop(void)
}
wsi_handle_thread = -1;
- destroy_wsi_conn(context);
+ destroy_wsi_conn(__context);
pstate = PSTATE_DEFAULT;
}
diff --git a/packaging/swap-manager.spec b/packaging/swap-manager.spec
index 45c5f51..fe7ac3d 100644
--- a/packaging/swap-manager.spec
+++ b/packaging/swap-manager.spec
@@ -10,7 +10,7 @@ Source: %{name}_%{version}.tar.gz
# setup config
%define NSP_SUPPORT 0
%define WSP_SUPPORT 0
-%define WSI_SUPPORT 0
+%define WSI_SUPPORT 1
%define WAYLAND_SUPPORT 0
%if "%{_with_wayland}" == "1"
@@ -56,7 +56,12 @@ BuildRequires: pkgconfig(tizen-extension-client)
%define NSP_SUPPORT 1
# FIXME: add WSP_SUPPORT wrt webkit2-efl and webkit2-efl-debuginfo
-# FIXME: add WSI_SUPPORT libwebsockets-devel
+
+%if %{WSI_SUPPORT}
+BuildRequires: pkgconfig(chromium-efl)
+BuildRequires: chromium-efl-debuginfo
+BuildRequires: pkgconfig(libwebsockets)
+%endif
Requires: swap-modules
Requires: swap-probe
diff --git a/scripts/gen_wsi_prof.sh b/scripts/gen_wsi_prof.sh
index 7890ef0..ce9b053 100755
--- a/scripts/gen_wsi_prof.sh
+++ b/scripts/gen_wsi_prof.sh
@@ -23,13 +23,13 @@ source $script_dir/dyn_vars
if [ "$__tizen_profile_name__" == "tv" ]; then
webkit_package_name=webkit2-efl-tv
else
- webkit_package_name=webkit2-efl
+ webkit_package_name=chromium-efl
fi
if [ "$__tizen_product_tv__" == "1" ]; then
- lib_file=$(rpm -ql ${webkit_package_name} | grep "/usr/lib/libewebkit2.so$" | head -1)
+ lib_file=$(rpm -ql ${webkit_package_name} | grep "/usr/lib/libchromium-ewk.so" | head -1)
else
- lib_file=$(rpm -ql ${webkit_package_name}-debuginfo | grep "/usr/lib/debug/usr/lib/libewebkit2.so.debug$" | head -1)
+ lib_file=$(rpm -ql ${webkit_package_name}-debuginfo | grep "/usr/lib/debug/usr/lib/libchromium-ewk.so.debug" | head -1)
fi
tmp=$(mktemp)
@@ -41,18 +41,16 @@ if [ "$__tizen_profile_name__" == "tv" ]; then
else
func_names+=(ewk_context_inspector_server_start)
fi
-func_names+=(_ZN3JSC16ProfileGenerator11willExecuteEPNS_9ExecStateERKNS_14CallIdentifierE)
-func_names+=(_ZN3JSC16ProfileGenerator10didExecuteEPNS_9ExecStateERKNS_14CallIdentifierE)
+func_names+=(_ZN2v88internal11ProfileNode14FindOrAddChildEPNS0_9CodeEntryE)
addrs=(`get_addrs ${func_names[@]}`)
inspector_addr=${addrs[0]}
-willexecute_addr=${addrs[1]}
-didexecute_addr=${addrs[2]}
+tick_addr=${addrs[1]}
rm ${tmp}
-if [ -z "${inspector_addr}" -o -z "${willexecute_addr}" -o -z "${didexecute_addr}" ]; then
+if [ -z "${inspector_addr}" -o -z "${tick_addr}" ]; then
exit 1
fi
@@ -66,8 +64,7 @@ cat << EOF
static const unsigned long INSPECTOR_ADDR = ${inspector_addr};
-static const unsigned long WILLEXECUTE_ADDR = ${willexecute_addr};
-static const unsigned long DIDEXECUTE_ADDR = ${didexecute_addr};
+static const unsigned long TICK_PROBE_ADDR = ${tick_addr};
#endif /* WSI_PROF_H_ */
EOF