/*
 * Copyright (c) 2001, Adam Dunkels.
 * All rights reserved. 
 *
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions 
 * are met: 
 * 1. Redistributions of source code must retain the above copyright 
 *    notice, this list of conditions and the following disclaimer. 
 * 2. Redistributions in binary form must reproduce the above copyright 
 *    notice, this list of conditions and the following disclaimer in the 
 *    documentation and/or other materials provided with the distribution. 
 * 3. The name of the author may not be used to endorse or promote
 *    products derived from this software without specific prior
 *    written permission.  
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
 *
 * This file is part of the uIP TCP/IP stack.
 *
 * $Id: vnc-server.c,v 1.4 2004/08/09 20:32:28 adamdunkels Exp $
 *
 */

/* A micro implementation of a VNC server. VNC is a protocol for
   remote network displays. See http://www.uk.research.att.com/vnc/
   for information about VNC.

   Initialization states:

   VNC_VERSION (send version string)
   VNC_AUTH    (send auth message)
   VNC_INIT    (send init message)

   Steady state:
   
   VNC_RUNNING (send RFB updates, parse incoming messages)

   What kind of message should be sent:

   SEND_NONE   (No message)
   SEND_BLANK  (Blank screen initially)
   SEND_SCREEN (Send entire screen, initially)
   SEND_UPDATE (Send incremental update)

*/

#include "uip.h"
#include "vnc-server.h"
#include "vnc-out.h"

#include <string.h>

/* RFB server initial handshaking string. */
#define RFB_SERVER_VERSION_STRING rfb_server_version_string

/* "RFB 003.003" */
static u8_t rfb_server_version_string[12] = {82,70,66,32,48,48,51,46,48,48,51,10};

/* uVNC */
static u8_t uvnc_name[4] = {117,86,78,67};
#if 1
#define PRINTF(x)
#else
#define PRINTF(x) printf x
#endif

/*-----------------------------------------------------------------------------------*/
u8_t
vnc_server_draw_rect(u8_t *ptr, u16_t x, u16_t y, u16_t w, u16_t h, u8_t c)
{
  register struct rfb_fb_update_rect_hdr *recthdr;
  struct rfb_rre_hdr *rrehdr;

  recthdr = (struct rfb_fb_update_rect_hdr *)ptr;
  rrehdr = (struct rfb_rre_hdr *)(ptr + sizeof(struct rfb_fb_update_rect_hdr));
  
  recthdr->rect.x = x;
  recthdr->rect.y = y;
  recthdr->rect.w = w;
  recthdr->rect.h = h; 
  recthdr->encoding[0] =
    recthdr->encoding[1] =
    recthdr->encoding[2] = 0;
  recthdr->encoding[3] = RFB_ENC_RRE;
      
  rrehdr->subrects[0] =
    rrehdr->subrects[1] = 0;
  rrehdr->bgpixel = c;
      
  return sizeof(struct rfb_fb_update_rect_hdr) + sizeof(struct rfb_rre_hdr);
}
/*-----------------------------------------------------------------------------------*/
void
vnc_server_init(void)
{
  vnc_out_init();
}
/*-----------------------------------------------------------------------------------*/
static void
vnc_send_blank(struct vnc_server_state *vs)
{
  switch(vs->type) {
  case 0:	
    vnc_out_send_blank(vs);
    break;
    /*  case 1:
    vnc_stats_send_blank(vs);
    break;   */
  }
}
/*-----------------------------------------------------------------------------------*/
static void
vnc_send_screen(struct vnc_server_state *vs)
{
  switch(vs->type) {
  case 0:	
    vnc_out_send_screen(vs);
    break;
    /*  case 1:
    vnc_stats_send_screen(vs);
    break;*/
  }
}
/*-----------------------------------------------------------------------------------*/
static void
vnc_send_update(struct vnc_server_state *vs)
{
  switch(vs->type) {
  case 0:	
    vnc_out_send_update(vs);
    break;
    /*  case 1:
    vnc_stats_send_update(vs);
    break;*/
  }
}
/*-----------------------------------------------------------------------------------*/
void
vnc_server_send_data(struct vnc_server_state *vs)
{
  register struct rfb_server_init *initmsg;
  
  switch(vs->state) {
  case VNC_VERSION:
    uip_send(RFB_SERVER_VERSION_STRING, sizeof(RFB_SERVER_VERSION_STRING));
    break;
  case VNC_AUTH:
    uip_appdata[0] = 0;
    uip_appdata[1] = 0;
    uip_appdata[2] = 0;
    uip_appdata[3] = RFB_AUTH_NONE;
    uip_send(uip_appdata, 4);
    break;
  case VNC_INIT:
    initmsg = (struct rfb_server_init *)uip_appdata;
    initmsg->width = htons(vs->width);
    initmsg->height = htons(vs->height);
    /* BGR233 pixel format. */
    initmsg->format.bps = 8;
    initmsg->format.depth = 8;
    initmsg->format.endian = 1;
    initmsg->format.truecolor = 1;
    initmsg->format.red_max = htons(7);
    initmsg->format.green_max = htons(7);
    initmsg->format.blue_max = htons(3);
    initmsg->format.red_shift = 0;
    initmsg->format.green_shift = 3;
    initmsg->format.blue_shift = 6;
    initmsg->namelength[0] = 0;
    initmsg->namelength[1] = 0;
    initmsg->namelength[2] = 0;	    
    initmsg->namelength[3] = 4;
    memcpy(&uip_appdata[sizeof(struct rfb_server_init)], uvnc_name, 4);
    /*    uip_appdata[sizeof(struct rfb_server_init)+0] = 'u';
    uip_appdata[sizeof(struct rfb_server_init)+1] = 'V';
    uip_appdata[sizeof(struct rfb_server_init)+2] = 'N';
    uip_appdata[sizeof(struct rfb_server_init)+3] = 'C';*/
    uip_send(uip_appdata, sizeof(struct rfb_server_init) + 4);
    break;
  case VNC_RUNNING:
    switch(vs->sendmsg) {
    case SEND_NONE:
      PRINTF(("Sending none\n"));
      break;
      
    case SEND_BLANK:
    case SENT_BLANK:
      PRINTF(("Sending blank\n"));
      vnc_send_blank(vs);
      break;
      
    case SEND_SCREEN:
      PRINTF(("Sending screen\n"));
      vnc_send_screen(vs);
      break;

    case SEND_UPDATE:
      PRINTF(("Sending update\n"));
      vnc_send_update(vs);
      break;
    }
    break;
    
  default:
    break;
  }

}
/*-----------------------------------------------------------------------------------*/
static void
vnc_key_event(struct vnc_server_state *vs)
{
  switch(vs->type) {
  case 0:	
    vnc_out_key_event(vs);
    break;
    /*  case 1:
    vnc_stats_key_event(vs);
    break;*/
  }
}
/*-----------------------------------------------------------------------------------*/
static void
vnc_pointer_event(struct vnc_server_state *vs)
{
  switch(vs->type) {
  case 0:	
    vnc_out_pointer_event(vs);
    break;
    /*  case 1:
    vnc_stats_pointer_event(vs);
    break;*/
  }
}
/*-----------------------------------------------------------------------------------*/
static u8_t
vnc_read_data(register struct vnc_server_state *vs)
{
  u8_t *appdata;
  u16_t len;
  struct rfb_fb_update_request *req;
  /*  u8_t niter;*/
  
  len = uip_datalen();
  appdata = (u8_t *)uip_appdata;
  
  /* First, check if there is data left to discard since last read. */
  if(vs->readlen > 0) {
    appdata += vs->readlen;
    if(len > vs->readlen) {
      len -= vs->readlen;
      vs->readlen = 0;
    } else {
      vs->readlen -= len;
      len = 0;
    }
  }

  if(vs->readlen != 0) {
    return 1;
  }

  /* All data read and ignored, parse next message. */
  /*  for(niter = 32; niter > 0 && len > 0; --niter) {*/
  while(len > 0) {
    switch(vs->state) {
    case VNC_VERSION:
    case VNC_VERSION2:
      PRINTF(("Read in version\n"));
      /* Receive and ignore client version string (12 bytes). */
      vs->state = VNC_AUTH;
      vs->readlen = 12;
      break;
      
    case VNC_AUTH:
    case VNC_AUTH2:
      PRINTF(("Read in auth \n"));
      /* Read and discard initialization from client (1 byte). */
      vs->readlen = 1;
      vs->state = VNC_INIT;
      break;
      
    case VNC_INIT:
    case VNC_INIT2:
      PRINTF(("Read in init \n"));
      vs->readlen = 0;
      vs->state = VNC_RUNNING;
      
    case VNC_RUNNING:
      /* Handle all client events. */
      switch(*appdata) {
      case RFB_SET_PIXEL_FORMAT:
	PRINTF(("Set pixel format\n"));
	vs->readlen = sizeof(struct rfb_set_pixel_format);
	/* Check if client runs with BGR233 format. If not, abort the
	   connection. */
	/* XXX: not implemented yet. */
	break;
	
      case RFB_FIX_COLORMAP_ENTRIES:
	PRINTF(("Fix colormap entries\n"));
	return 0;
	
      case RFB_SET_ENCODINGS:
	PRINTF(("Set encodings\n"));
	vs->readlen = sizeof(struct rfb_set_encoding);
	vs->readlen += htons(((struct rfb_set_encoding *)appdata)->encodings) * 4;
	/* Make sure that client supports the encodings we use. */
	/* XXX: not implemented yet. */
	break;
	
      case RFB_FB_UPDATE_REQ:
	PRINTF(("Update request\n"));
	vs->update_requested = 1;
	vs->readlen = sizeof(struct rfb_fb_update_request);
	/* blank the screen initially */
	req = (struct rfb_fb_update_request *)appdata;
	if(req->incremental == 0) {
	  /*	  vs->sendmsg = SEND_BLANK;*/
	  vnc_out_update_area(vs, 0, 0, vs->w, vs->h);
	}
	break;
	
      case RFB_KEY_EVENT:
	vs->readlen = sizeof(struct rfb_key_event);
	vnc_key_event(vs);
	break;
	
      case RFB_POINTER_EVENT:
	vs->readlen = sizeof(struct rfb_pointer_event);
	vnc_pointer_event(vs);
	break;
	
      case RFB_CLIENT_CUT_TEXT:
	PRINTF(("Client cut text\n"));

	if(((struct rfb_client_cut_text *)appdata)->len[0] != 0 ||
	   ((struct rfb_client_cut_text *)appdata)->len[1] != 0) {
	  return 0;
	  
	}
	vs->readlen = sizeof(struct rfb_client_cut_text) +
	  (((struct rfb_client_cut_text *)appdata)->len[2] << 8) +
	  ((struct rfb_client_cut_text *)appdata)->len[3];
	/*	return 0;*/
	break;
	
      default:
	PRINTF(("Unknown message %d\n", *appdata));
	return 0;
      }
      break;
      
    default:
      return 0;
    }

    if(vs->readlen > 0) {
      if(len > vs->readlen) {
	len -= vs->readlen;
	appdata += vs->readlen;
	vs->readlen = 0;
      } else {
	vs->readlen -= len;
	len = 0;
      }
    } else {
      /* Lost data. */
      break;
    }
    
  }

  /*  if(vs->readlen > 0) {
    printf("More data %d\n", vs->readlen);
    }*/
  
  /*  uip_appdata = appdata;*/

  return 1;
}
/*-----------------------------------------------------------------------------------*/
static void
vnc_new(register struct vnc_server_state *vs)
{
  vs->counter = 0;
  vs->readlen = 0;
  vs->sendmsg = SEND_NONE;
  vs->update_requested = 1;
  switch(vs->type) {
  case 0:	
    vnc_out_new(vs);
    break;
    /*  case 1:
    vnc_stats_new(vs);
    break;*/
  }
}
/*-----------------------------------------------------------------------------------*/
static void
vnc_acked(register struct vnc_server_state *vs)
{
  switch(vs->state) {
  case VNC_VERSION:
    vs->state = VNC_VERSION2;
    break;
    
  case VNC_AUTH:
    vs->state = VNC_AUTH2;
    break;
    
  case VNC_INIT:
    vs->state = VNC_INIT2;
    break;

  case VNC_RUNNING:
    switch(vs->type) {
    case 0:	
      vnc_out_acked(vs);
      break;
      /*    case 1:
      vnc_stats_acked(vs);
      break;*/
    }
    break;
  }
}
/*-----------------------------------------------------------------------------------*/
void
vnc_server_appcall(struct vnc_server_state *vs)
{
  
  vs->type = htons(uip_conn->lport) - 5900;
  
  if(uip_connected()) {      
    vnc_new(vs);
    vs->state = VNC_VERSION;
    vnc_server_send_data(vs);
    return;
  }
  if(uip_acked()) {
    PRINTF(("Acked\n"));
    vnc_acked(vs);
  }
  
  if(uip_newdata()) {
    PRINTF(("Newdata\n"));
    vs->counter = 0;
    if(vnc_read_data(vs) == 0) {
      uip_abort();
      return;
    }
  }
  
  if(uip_rexmit()) {
    PRINTF(("Rexmit\n"));
  }
  
  
  if(uip_newdata() ||
     uip_rexmit() ||
     uip_acked()) {
    vnc_server_send_data(vs);
  } else if(uip_poll()) {
    ++vs->counter;
    /* Abort connection after about 20 seconds of inactivity. */
    if(vs->counter >= 40) {
      uip_abort();
      return;
    }
    
    vnc_out_poll(vs);
  }
  
}
/*-----------------------------------------------------------------------------------*/
