Commit 08a8d9d5 authored by Vincent Wei's avatar Vincent Wei
Browse files

debug

parent 62cad89d
......@@ -67,7 +67,7 @@ int save_dirty_pixels_to_png (const char* file_name, const USClient* us_client)
return -3;
}
pixel_rows = (png_bytepp)png_malloc (png_ptr, height * sizeof (png_bytep));
pixel_rows = (png_bytepp)malloc (height * sizeof (png_bytep));
if (!pixel_rows) {
LOG (("save_dirty_pixels_to_png: failed to allocate memory for pixel_rows: %d\n", height));
retval = 1;
......@@ -98,26 +98,25 @@ int save_dirty_pixels_to_png (const char* file_name, const USClient* us_client)
us_client->rc_dirty.right - us_client->rc_dirty.left,
us_client->rc_dirty.bottom - us_client->rc_dirty.top,
8, /* bit_depth */
(us_client->vfb_info.type == COMMLCD_TRUE_RGB565)?PNG_COLOR_TYPE_RGB:PNG_COLOR_TYPE_RGB_ALPHA,
PNG_COLOR_TYPE_RGB,
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
{
int bytes_per_pixel;
png_color_8 sig_bit;
if (us_client->vfb_info.type == COMMLCD_TRUE_RGB565) {
bytes_per_pixel = 3;
bytes_per_pixel = 3;
if (us_client->vfb_info.type == USVFB_TRUE_RGB565) {
sig_bit.red = 5;
sig_bit.green = 6;
sig_bit.blue = 5;
sig_bit.alpha = 0;
}
else if (us_client->vfb_info.type == COMMLCD_TRUE_RGB8888) {
bytes_per_pixel = 4;
else if (us_client->vfb_info.type == USVFB_TRUE_RGB0888) {
sig_bit.red = 8;
sig_bit.green = 8;
sig_bit.blue = 8;
sig_bit.alpha = 8;
sig_bit.alpha = 0;
}
png_set_sBIT (png_ptr, info_ptr, &sig_bit);
......@@ -134,7 +133,7 @@ int save_dirty_pixels_to_png (const char* file_name, const USClient* us_client)
error:
if (pixel_rows)
png_free (png_ptr, pixel_rows);
free (pixel_rows);
if (png_ptr)
png_destroy_write_struct (&png_ptr, &info_ptr);
if (png_file)
......
......@@ -135,11 +135,12 @@ int us_accept (int listenfd, pid_t *pidptr, uid_t *uidptr)
static struct _demo_info {
char* const demo_name;
char* const working_dir;
char* const exe_file;
char* const def_mode;
} _demo_list [] = {
{"mguxdemo", "/usr/local/bin/mguxdemo", "480x640-16bpp"},
{"cbplusui", "/usr/local/bin/cbplusui", "240x240-16bpp"},
{"mguxdemo", "/usr/local/bin/", "/usr/local/bin/mguxdemo", "480x640-16bpp"},
{"cbplusui", "/usr/local/bin/", "/usr/local/bin/cbplusui", "240x240-16bpp"},
};
pid_t us_launch_client (const char* demo_name)
......@@ -162,10 +163,15 @@ pid_t us_launch_client (const char* demo_name)
ACCESS_LOG (("fork child for %s\n", demo_name));
}
else if (pid == 0) {
int retval;
char env_mode [32];
retval = chdir (_demo_list[found].working_dir);
if (retval)
perror ("chdir");
strcpy (env_mode, "MG_DEFAULTMODE=");
strcat (env_mode, _demo_list[found].def_mode);
char *const argv[] = {_demo_list[found].demo_name, NULL};
char *const envp[] = {"MG_GAL_ENGINE=usvfb", "MG_IAL_ENGINE=usvfb", env_mode, NULL};
if (execve (_demo_list[found].exe_file, argv, envp) < 0)
......@@ -193,20 +199,22 @@ int us_on_connected (USClient* us_client)
/* read info of virtual frame buffer */
n = read (us_client->fd, &header, sizeof (struct _frame_header));
if (n < sizeof (struct _frame_header) || header.type != FT_VFBINFO) {
printf ("us_on_connected: frame header info: %ld, %d.\n", n, header.type);
retval = 1;
goto error;
}
n = read (us_client->fd, &us_client->vfb_info, sizeof (struct _vfb_info));
if (n < header.payload_len) {
retval = 2;
goto error;
}
if (us_client->vfb_info.type == COMMLCD_TRUE_RGB565) {
if (us_client->vfb_info.type == USVFB_TRUE_RGB565) {
us_client->bytes_per_pixel = 3;
us_client->row_pitch = us_client->vfb_info.width * 3;
}
else if (us_client->vfb_info.type == COMMLCD_TRUE_RGB8888) {
else if (us_client->vfb_info.type == USVFB_TRUE_RGB0888) {
us_client->bytes_per_pixel = 3;
us_client->row_pitch = us_client->vfb_info.width * 3;
}
......@@ -259,12 +267,17 @@ int us_on_client_data (USClient* us_client)
struct _frame_header header;
n = read (us_client->fd, &header, sizeof (struct _frame_header));
if (n == 0) {
return 0;
}
if (n < sizeof (struct _frame_header)) {
printf ("us_on_client_data: read bytes %ld\n", n);
return 1;
}
if (header.type == FT_DIRTYPIXELS) {
int y;
int y, Bpp_vfb;
RECT rc_dirty;
n = read (us_client->fd, &rc_dirty, sizeof (RECT));
......@@ -278,13 +291,20 @@ int us_on_client_data (USClient* us_client)
return 3;
}
if (us_client->vfb_info.type == USVFB_TRUE_RGB565) {
Bpp_vfb = 2;
}
else {
Bpp_vfb = 4;
}
uint8_t* dst_pixel = us_client->shadow_fb + us_client->row_pitch * rc_dirty.top + rc_dirty.left * us_client->bytes_per_pixel;
int dirty_pixels = rc_dirty.right - rc_dirty.left;
for (y = rc_dirty.top; y < rc_dirty.bottom; y++) {
n = read (us_client->fd, buff, (rc_dirty.right - rc_dirty.left) * us_client->bytes_per_pixel);
n = read (us_client->fd, buff, (rc_dirty.right - rc_dirty.left) * Bpp_vfb);
uint8_t* src_pixel = (uint8_t*)buff;
if (us_client->bytes_per_pixel == 4) {
if (Bpp_vfb == 4) {
for (int x = 0; x < dirty_pixels; x++) {
uint32_t pixel = *((uint32_t*)src_pixel);
dst_pixel [x*3 + 0] = (uint8_t)((pixel&0xFF0000)>>16);
......@@ -319,6 +339,7 @@ int us_on_client_data (USClient* us_client)
}
else {
LOG (("us_on_client_data: unknown data type: %d\n", header.type));
return 3;
}
return 0;
......@@ -328,8 +349,8 @@ int us_check_dirty_pixels (const USClient* us_client)
{
struct timeval now;
if ((us_client->rc_dirty.right - us_client->rc_dirty.left) > 0
&& (us_client->rc_dirty.bottom - us_client->rc_dirty.top) > 0)
if ((us_client->rc_dirty.right - us_client->rc_dirty.left) <= 0
&& (us_client->rc_dirty.bottom - us_client->rc_dirty.top) <= 0)
return 0;
gettimeofday (&now, NULL);
......
......@@ -147,12 +147,13 @@ setup_signals (void)
static int
onopen (WSClient * client)
{
pid_t pid_usc;
pid_t pid_usc;
pid_usc = us_launch_client (client->headers->path + 1);
pid_usc = us_launch_client (client->headers->path + 1);
client->pid_buddy = pid_usc;
printf ("INFO: Got a request from client (%d) %s and fork a child %d\n", client->listener, client->headers->path, pid_usc);
return 0;
printf ("INFO: Got a request from client (%d) %s and fork a child %d\n", client->listener, client->headers->path, pid_usc);
return 0;
}
static int
......
......@@ -31,8 +31,13 @@
#define WD_VERSION "0.8"
/* The pixel format */
#define COMMLCD_TRUE_RGB565 3
#define COMMLCD_TRUE_RGB8888 4
#define USVFB_PSEUDO_RGB332 1
#define USVFB_TRUE_RGB555 2
#define USVFB_TRUE_RGB565 3
#define USVFB_TRUE_RGB888 4
#define USVFB_TRUE_RGB0888 5
#define USVFB_TRUE_ARGB1555 6
#define USVFB_TRUE_ARGB8888 7
struct _vfb_info {
short height;
......
......@@ -55,6 +55,7 @@
#include "wdserver.h"
#include "websocket.h"
#include "unixsocket.h"
#include "pixelencoder.h"
#include "base64.h"
#include "log.h"
......@@ -2297,7 +2298,7 @@ set_rfds_wfds (int ws_listener, int us_listener, WSServer * server)
}
}
/* Only if we have data to send the client */
/* Only if we have data to send to the WebSocket client */
if (client->status & WS_SENDING) {
FD_SET (ws_fd, &fdstate.wfds);
if (ws_fd > max_file_fd)
......@@ -2327,7 +2328,7 @@ ws_get_client_from_list_by_buddy (pid_t pid, GSLList ** colist)
{
GSLList *match = NULL;
/* Find the client data for the socket in use */
/* Find the client matched the pid */
if (!(match = list_find (*colist, ws_find_client_pid_in_list, &pid)))
return NULL;
return (WSClient *) match->data;
......@@ -2353,6 +2354,9 @@ handle_us_accept (int listener, WSServer * server)
return;
}
client->us_buddy->fd = newfd;
client->us_buddy->pid = pid_buddy;
LOG (("Accepted UnixSocket client: %d\n", pid_buddy));
retval = us_on_connected (client->us_buddy);
......@@ -2361,57 +2365,104 @@ handle_us_accept (int listener, WSServer * server)
}
}
/* Handle a UNIX read. */
/* Handle a UnixSocket read. */
static void
handle_us_reads (int conn, WSServer * server)
handle_us_reads (USClient *us_client, WSClient* ws_client, WSServer* server)
{
WSClient *client = NULL;
int retval;
if (!(client = ws_get_client_from_list (conn, &server->colist)))
return;
#ifdef HAVE_LIBSSL
if (handle_ssl_pending_rw (conn, server, client) == 0)
return;
#endif
/* *INDENT-OFF* */
client->start_proc = client->end_proc = (struct timeval) {0};
/* *INDENT-ON* */
gettimeofday (&client->start_proc, NULL);
read_client_data (client, server);
/* An error ocurred while reading data or connection closed */
if ((client->status & WS_CLOSE)) {
handle_ws_read_close (conn, client, server);
if ((retval = us_on_client_data (us_client))) {
printf ("handle_us_reads: failed when calling us_on_client_data: %d\n", retval);
}
}
/* Handle a UNIX write close connection. */
/* Handle a UnixSocket write. */
static void
handle_us_write_close (int conn, WSClient * client, WSServer * server)
handle_us_writes (USClient *us_client, WSClient* ws_client, WSServer* server)
{
handle_tcp_close (conn, client, server);
}
/* Handle a UNIX write. */
static int
ws_send_dirty_pixels (WSClient* ws_client, const RECT* rc_dirty, const char* png_path)
{
int retval;
struct stat my_stat;
char* p = NULL;
FILE* fp;
size_t size;
if ((retval = stat (png_path, &my_stat))) {
retval = 1;
goto error;
}
if (!S_ISREG (my_stat.st_mode) || my_stat.st_size == 0) {
retval = 2;
goto error;
}
LOG (("Trying send content of file %s (size: %u) to client\n", png_path, my_stat.st_size));
p = xmalloc (sizeof (RECT) + my_stat.st_size);
if (p == NULL) {
retval = 3;
goto error;
}
memcpy (p, rc_dirty, sizeof (RECT));
fp = fopen (png_path, "r");
if (fp == NULL) {
retval = 4;
goto error;
}
size = fread (p + sizeof (RECT), sizeof (char), my_stat.st_size, fp);
if (size < my_stat.st_size) {
retval = 5;
goto error;
}
retval = ws_send_data (ws_client, WS_OPCODE_BIN, p, sizeof (RECT) + my_stat.st_size);
error:
if (p)
free (p);
return retval;
}
/* Check and send dirty pixels to WebSocket client */
static void
handle_us_writes (int conn, WSServer * server)
check_dirty_pixels (WSServer* server)
{
WSClient *client = NULL;
GSLList *client_node = server->colist;
WSClient *ws_client = NULL;
USClient *us_client = NULL;
if (!(client = ws_get_client_from_list (conn, &server->colist)))
return;
while (client_node) {
ws_client = (WSClient*)(client_node->data);
us_client = ws_client->us_buddy;
if (us_client && us_check_dirty_pixels (us_client)) {
int retval;
char png_path [20];
printf ("check_dirty_pixels: UnixSocket Client #%d has dirty pixels to send.\n", us_client->pid);
sprintf (png_path, "/tmp/wds-%d.png", us_client->pid);
if ((retval = save_dirty_pixels_to_png (png_path, us_client))) {
printf ("check_dirty_pixels: failed when calling save_dirty_pixels_to_png: %d\n", retval);
continue;
}
ws_respond (client, NULL, 0); /* buffered data */
/* done sending data */
if (client->sockqueue == NULL)
client->status &= ~WS_SENDING;
if ((retval = ws_send_dirty_pixels (ws_client, &us_client->rc_dirty, png_path))) {
printf ("check_dirty_pixels: failed when calling ws_send_dirty_pixels: %d\n", retval);
continue;
}
/* An error ocurred while sending data or while reading data but still
* waiting from the last send() from the server to the client. e.g.,
* sending status code */
if ((client->status & WS_CLOSE) && !(client->status & WS_SENDING))
handle_us_write_close (conn, client, server);
us_reset_dirty_pixels (us_client);
}
client_node = client_node->next;
}
}
/* Check and handle fds. */
......@@ -2419,7 +2470,8 @@ static void
check_rfds_wfds (int ws_listener, int us_listener, WSServer * server)
{
GSLList *client_node = server->colist;
WSClient *client = NULL;
WSClient *ws_client = NULL;
USClient *us_client = NULL;
/* handle new WebSocket connections */
if (FD_ISSET (ws_listener, &fdstate.rfds))
......@@ -2429,10 +2481,10 @@ check_rfds_wfds (int ws_listener, int us_listener, WSServer * server)
handle_us_accept (us_listener, server);
while (client_node) {
int ws_fd, us_fd;
int ws_fd;
client = (WSClient*)(client_node->data);
ws_fd = client->listener;
ws_client = (WSClient*)(client_node->data);
ws_fd = ws_client->listener;
/* handle reading data from a WebSocket client */
if (FD_ISSET (ws_fd, &fdstate.rfds))
......@@ -2441,15 +2493,15 @@ check_rfds_wfds (int ws_listener, int us_listener, WSServer * server)
else if (FD_ISSET (ws_fd, &fdstate.wfds))
handle_ws_writes (ws_fd, server);
if (client->us_buddy) {
us_fd = client->us_buddy->fd;
us_client = ws_client->us_buddy;
if (us_client) {
/* handle reading data from a UnixSocket client */
if (FD_ISSET (us_fd, &fdstate.rfds))
handle_us_reads (us_fd, server);
if (FD_ISSET (us_client->fd, &fdstate.rfds))
handle_us_reads (us_client, ws_client, server);
/* handle sending data to a UnixSocket client */
else if (FD_ISSET (us_fd, &fdstate.wfds))
handle_us_writes (us_fd, server);
else if (FD_ISSET (us_client->fd, &fdstate.wfds))
handle_us_writes (us_client, ws_client, server);
}
client_node = client_node->next;
......@@ -2461,7 +2513,8 @@ check_rfds_wfds (int ws_listener, int us_listener, WSServer * server)
void
ws_start (WSServer * server)
{
int ws_listener = 0, us_listener = 0;
int ws_listener = 0, us_listener = 0, retval;
struct timeval timeout = {0, 20000}; /* 20 ms */
#ifdef HAVE_LIBSSL
if (wsconfig.sslcert && wsconfig.sslkey) {
......@@ -2488,7 +2541,14 @@ ws_start (WSServer * server)
/* yep, wait patiently */
/* should it be using epoll/kqueue? will see... */
if (select (max_file_fd, &fdstate.rfds, &fdstate.wfds, NULL, NULL) == -1) {
retval = select (max_file_fd, &fdstate.rfds, &fdstate.wfds, NULL, &timeout);
if (retval == 0) {
check_dirty_pixels (server);
}
else if (retval > 0) {
check_rfds_wfds (ws_listener, us_listener, server);
}
else {
switch (errno) {
case EINTR:
break;
......@@ -2496,8 +2556,6 @@ ws_start (WSServer * server)
FATAL ("Unable to select: %s.", strerror (errno));
}
}
check_rfds_wfds (ws_listener, us_listener, server);
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment