Contiki 2.6
|
00001 /* 00002 * Copyright (c) 2001, Adam Dunkels. 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions 00007 * are met: 00008 * 1. Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * 3. The name of the author may not be used to endorse or promote 00014 * products derived from this software without specific prior 00015 * written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 00018 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00019 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00020 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 00021 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00022 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 00023 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00024 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 00025 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00026 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00027 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00028 * 00029 * This file is part of the uIP TCP/IP stack. 00030 * 00031 * $Id: vnc-server.c,v 1.3 2010/10/19 18:29:04 adamdunkels Exp $ 00032 * 00033 */ 00034 00035 /* A micro implementation of a VNC server. VNC is a protocol for 00036 remote network displays. See http://www.uk.research.att.com/vnc/ 00037 for information about VNC. 00038 00039 Initialization states: 00040 00041 VNC_VERSION (send version string) 00042 VNC_AUTH (send auth message) 00043 VNC_INIT (send init message) 00044 00045 Steady state: 00046 00047 VNC_RUNNING (send RFB updates, parse incoming messages) 00048 00049 What kind of message should be sent: 00050 00051 SEND_NONE (No message) 00052 SEND_BLANK (Blank screen initially) 00053 SEND_SCREEN (Send entire screen, initially) 00054 SEND_UPDATE (Send incremental update) 00055 00056 */ 00057 00058 #include "contiki-net.h" 00059 #include "ctk/vnc-server.h" 00060 #include "ctk/vnc-out.h" 00061 00062 #include <string.h> 00063 00064 /* RFB server initial handshaking string. */ 00065 #define RFB_SERVER_VERSION_STRING rfb_server_version_string 00066 00067 /* "RFB 003.003" */ 00068 static uint8_t rfb_server_version_string[12] = {82,70,66,32,48,48,51,46,48,48,51,10}; 00069 00070 /* uVNC */ 00071 static uint8_t uvnc_name[4] = {117,86,78,67}; 00072 #if 1 00073 #define PRINTF(x) 00074 #else 00075 #define PRINTF(x) printf x 00076 #endif 00077 00078 /*-----------------------------------------------------------------------------------*/ 00079 uint8_t 00080 vnc_server_draw_rect(uint8_t *ptr, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint8_t c) 00081 { 00082 register struct rfb_fb_update_rect_hdr *recthdr; 00083 struct rfb_rre_hdr *rrehdr; 00084 00085 recthdr = (struct rfb_fb_update_rect_hdr *)ptr; 00086 rrehdr = (struct rfb_rre_hdr *)(ptr + sizeof(struct rfb_fb_update_rect_hdr)); 00087 00088 recthdr->rect.x = x; 00089 recthdr->rect.y = y; 00090 recthdr->rect.w = w; 00091 recthdr->rect.h = h; 00092 recthdr->encoding[0] = 00093 recthdr->encoding[1] = 00094 recthdr->encoding[2] = 0; 00095 recthdr->encoding[3] = RFB_ENC_RRE; 00096 00097 rrehdr->subrects[0] = 00098 rrehdr->subrects[1] = 0; 00099 rrehdr->bgpixel = c; 00100 00101 return sizeof(struct rfb_fb_update_rect_hdr) + sizeof(struct rfb_rre_hdr); 00102 } 00103 /*-----------------------------------------------------------------------------------*/ 00104 void 00105 vnc_server_init(void) 00106 { 00107 vnc_out_init(); 00108 } 00109 /*-----------------------------------------------------------------------------------*/ 00110 static void 00111 vnc_send_blank(struct vnc_server_state *vs) 00112 { 00113 switch(vs->type) { 00114 case 0: 00115 vnc_out_send_blank(vs); 00116 break; 00117 /* case 1: 00118 vnc_stats_send_blank(vs); 00119 break; */ 00120 } 00121 } 00122 /*-----------------------------------------------------------------------------------*/ 00123 static void 00124 vnc_send_screen(struct vnc_server_state *vs) 00125 { 00126 switch(vs->type) { 00127 case 0: 00128 vnc_out_send_screen(vs); 00129 break; 00130 /* case 1: 00131 vnc_stats_send_screen(vs); 00132 break;*/ 00133 } 00134 } 00135 /*-----------------------------------------------------------------------------------*/ 00136 static void 00137 vnc_send_update(struct vnc_server_state *vs) 00138 { 00139 switch(vs->type) { 00140 case 0: 00141 vnc_out_send_update(vs); 00142 break; 00143 /* case 1: 00144 vnc_stats_send_update(vs); 00145 break;*/ 00146 } 00147 } 00148 /*-----------------------------------------------------------------------------------*/ 00149 void 00150 vnc_server_send_data(struct vnc_server_state *vs) 00151 { 00152 register struct rfb_server_init *initmsg; 00153 00154 switch(vs->state) { 00155 case VNC_VERSION: 00156 uip_send(RFB_SERVER_VERSION_STRING, sizeof(RFB_SERVER_VERSION_STRING)); 00157 break; 00158 case VNC_AUTH: 00159 ((char *)uip_appdata)[0] = 0; 00160 ((char *)uip_appdata)[1] = 0; 00161 ((char *)uip_appdata)[2] = 0; 00162 ((char *)uip_appdata)[3] = RFB_AUTH_NONE; 00163 uip_send(uip_appdata, 4); 00164 break; 00165 case VNC_INIT: 00166 initmsg = (struct rfb_server_init *)uip_appdata; 00167 initmsg->width = uip_htons(vs->width); 00168 initmsg->height = uip_htons(vs->height); 00169 /* BGR233 pixel format. */ 00170 initmsg->format.bps = 8; 00171 initmsg->format.depth = 8; 00172 initmsg->format.endian = 1; 00173 initmsg->format.truecolor = 1; 00174 initmsg->format.red_max = uip_htons(7); 00175 initmsg->format.green_max = uip_htons(7); 00176 initmsg->format.blue_max = uip_htons(3); 00177 initmsg->format.red_shift = 0; 00178 initmsg->format.green_shift = 3; 00179 initmsg->format.blue_shift = 6; 00180 initmsg->namelength[0] = 0; 00181 initmsg->namelength[1] = 0; 00182 initmsg->namelength[2] = 0; 00183 initmsg->namelength[3] = 4; 00184 memcpy(&((char *)uip_appdata)[sizeof(struct rfb_server_init)], uvnc_name, 4); 00185 /* ((char *)uip_appdata)[sizeof(struct rfb_server_init)+0] = 'u'; 00186 ((char *)uip_appdata)[sizeof(struct rfb_server_init)+1] = 'V'; 00187 ((char *)uip_appdata)[sizeof(struct rfb_server_init)+2] = 'N'; 00188 ((char *)uip_appdata)[sizeof(struct rfb_server_init)+3] = 'C';*/ 00189 uip_send(uip_appdata, sizeof(struct rfb_server_init) + 4); 00190 break; 00191 case VNC_RUNNING: 00192 switch(vs->sendmsg) { 00193 case SEND_NONE: 00194 PRINTF(("Sending none\n")); 00195 break; 00196 00197 case SEND_BLANK: 00198 case SENT_BLANK: 00199 PRINTF(("Sending blank\n")); 00200 vnc_send_blank(vs); 00201 break; 00202 00203 case SEND_SCREEN: 00204 PRINTF(("Sending screen\n")); 00205 vnc_send_screen(vs); 00206 break; 00207 00208 case SEND_UPDATE: 00209 PRINTF(("Sending update\n")); 00210 vnc_send_update(vs); 00211 break; 00212 } 00213 break; 00214 00215 default: 00216 break; 00217 } 00218 00219 } 00220 /*-----------------------------------------------------------------------------------*/ 00221 static void 00222 vnc_key_event(struct vnc_server_state *vs) 00223 { 00224 switch(vs->type) { 00225 case 0: 00226 vnc_out_key_event(vs); 00227 break; 00228 /* case 1: 00229 vnc_stats_key_event(vs); 00230 break;*/ 00231 } 00232 } 00233 /*-----------------------------------------------------------------------------------*/ 00234 static void 00235 vnc_pointer_event(struct vnc_server_state *vs) 00236 { 00237 switch(vs->type) { 00238 case 0: 00239 vnc_out_pointer_event(vs); 00240 break; 00241 /* case 1: 00242 vnc_stats_pointer_event(vs); 00243 break;*/ 00244 } 00245 } 00246 /*-----------------------------------------------------------------------------------*/ 00247 static uint8_t 00248 vnc_read_data(CC_REGISTER_ARG struct vnc_server_state *vs) 00249 { 00250 uint8_t *appdata; 00251 uint16_t len; 00252 struct rfb_fb_update_request *req; 00253 /* uint8_t niter;*/ 00254 00255 len = uip_datalen(); 00256 appdata = (uint8_t *)uip_appdata; 00257 00258 /* First, check if there is data left to discard since last read. */ 00259 if(vs->readlen > 0) { 00260 appdata += vs->readlen; 00261 if(len > vs->readlen) { 00262 len -= vs->readlen; 00263 vs->readlen = 0; 00264 } else { 00265 vs->readlen -= len; 00266 len = 0; 00267 } 00268 } 00269 00270 if(vs->readlen != 0) { 00271 return 1; 00272 } 00273 00274 /* All data read and ignored, parse next message. */ 00275 /* for(niter = 32; niter > 0 && len > 0; --niter) {*/ 00276 while(len > 0) { 00277 switch(vs->state) { 00278 case VNC_VERSION: 00279 case VNC_VERSION2: 00280 PRINTF(("Read in version\n")); 00281 /* Receive and ignore client version string (12 bytes). */ 00282 vs->state = VNC_AUTH; 00283 vs->readlen = 12; 00284 break; 00285 00286 case VNC_AUTH: 00287 case VNC_AUTH2: 00288 PRINTF(("Read in auth \n")); 00289 /* Read and discard initialization from client (1 byte). */ 00290 vs->readlen = 1; 00291 vs->state = VNC_INIT; 00292 break; 00293 00294 case VNC_INIT: 00295 case VNC_INIT2: 00296 PRINTF(("Read in init \n")); 00297 vs->readlen = 0; 00298 vs->state = VNC_RUNNING; 00299 00300 case VNC_RUNNING: 00301 /* Handle all client events. */ 00302 switch(*appdata) { 00303 case RFB_SET_PIXEL_FORMAT: 00304 PRINTF(("Set pixel format\n")); 00305 vs->readlen = sizeof(struct rfb_set_pixel_format); 00306 /* Check if client runs with BGR233 format. If not, abort the 00307 connection. */ 00308 /* XXX: not implemented yet. */ 00309 break; 00310 00311 case RFB_FIX_COLORMAP_ENTRIES: 00312 PRINTF(("Fix colormap entries\n")); 00313 return 0; 00314 00315 case RFB_SET_ENCODINGS: 00316 PRINTF(("Set encodings\n")); 00317 vs->readlen = sizeof(struct rfb_set_encoding); 00318 vs->readlen += uip_htons(((struct rfb_set_encoding *)appdata)->encodings) * 4; 00319 /* Make sure that client supports the encodings we use. */ 00320 /* XXX: not implemented yet. */ 00321 break; 00322 00323 case RFB_FB_UPDATE_REQ: 00324 PRINTF(("Update request\n")); 00325 vs->update_requested = 1; 00326 vs->readlen = sizeof(struct rfb_fb_update_request); 00327 /* blank the screen initially */ 00328 req = (struct rfb_fb_update_request *)appdata; 00329 if(req->incremental == 0) { 00330 /* vs->sendmsg = SEND_BLANK;*/ 00331 vnc_out_update_area(vs, 0, 0, vs->w, vs->h); 00332 } 00333 break; 00334 00335 case RFB_KEY_EVENT: 00336 vs->readlen = sizeof(struct rfb_key_event); 00337 vnc_key_event(vs); 00338 break; 00339 00340 case RFB_POINTER_EVENT: 00341 vs->readlen = sizeof(struct rfb_pointer_event); 00342 vnc_pointer_event(vs); 00343 break; 00344 00345 case RFB_CLIENT_CUT_TEXT: 00346 PRINTF(("Client cut text\n")); 00347 00348 if(((struct rfb_client_cut_text *)appdata)->len[0] != 0 || 00349 ((struct rfb_client_cut_text *)appdata)->len[1] != 0) { 00350 return 0; 00351 00352 } 00353 vs->readlen = sizeof(struct rfb_client_cut_text) + 00354 (((struct rfb_client_cut_text *)appdata)->len[2] << 8) + 00355 ((struct rfb_client_cut_text *)appdata)->len[3]; 00356 /* return 0;*/ 00357 break; 00358 00359 default: 00360 PRINTF(("Unknown message %d\n", *appdata)); 00361 return 0; 00362 } 00363 break; 00364 00365 default: 00366 return 0; 00367 } 00368 00369 if(vs->readlen > 0) { 00370 if(len > vs->readlen) { 00371 len -= vs->readlen; 00372 appdata += vs->readlen; 00373 vs->readlen = 0; 00374 } else { 00375 vs->readlen -= len; 00376 len = 0; 00377 } 00378 } else { 00379 /* Lost data. */ 00380 break; 00381 } 00382 00383 } 00384 00385 /* if(vs->readlen > 0) { 00386 printf("More data %d\n", vs->readlen); 00387 }*/ 00388 00389 /* uip_appdata = appdata;*/ 00390 00391 return 1; 00392 } 00393 /*-----------------------------------------------------------------------------------*/ 00394 static void 00395 vnc_new(CC_REGISTER_ARG struct vnc_server_state *vs) 00396 { 00397 vs->counter = 0; 00398 vs->readlen = 0; 00399 vs->sendmsg = SEND_NONE; 00400 vs->update_requested = 1; 00401 switch(vs->type) { 00402 case 0: 00403 vnc_out_new(vs); 00404 break; 00405 /* case 1: 00406 vnc_stats_new(vs); 00407 break;*/ 00408 } 00409 } 00410 /*-----------------------------------------------------------------------------------*/ 00411 static void 00412 vnc_acked(CC_REGISTER_ARG struct vnc_server_state *vs) 00413 { 00414 switch(vs->state) { 00415 case VNC_VERSION: 00416 vs->state = VNC_VERSION2; 00417 break; 00418 00419 case VNC_AUTH: 00420 vs->state = VNC_AUTH2; 00421 break; 00422 00423 case VNC_INIT: 00424 vs->state = VNC_INIT2; 00425 break; 00426 00427 case VNC_RUNNING: 00428 switch(vs->type) { 00429 case 0: 00430 vnc_out_acked(vs); 00431 break; 00432 /* case 1: 00433 vnc_stats_acked(vs); 00434 break;*/ 00435 } 00436 break; 00437 } 00438 } 00439 /*-----------------------------------------------------------------------------------*/ 00440 void 00441 vnc_server_appcall(struct vnc_server_state *vs) 00442 { 00443 00444 vs->type = uip_htons(uip_conn->lport) - 5900; 00445 00446 if(uip_connected()) { 00447 vnc_new(vs); 00448 vs->state = VNC_VERSION; 00449 vnc_server_send_data(vs); 00450 return; 00451 } 00452 if(uip_acked()) { 00453 PRINTF(("Acked\n")); 00454 vnc_acked(vs); 00455 } 00456 00457 if(uip_newdata()) { 00458 PRINTF(("Newdata\n")); 00459 vs->counter = 0; 00460 if(vnc_read_data(vs) == 0) { 00461 uip_abort(); 00462 return; 00463 } 00464 } 00465 00466 if(uip_rexmit()) { 00467 PRINTF(("Rexmit\n")); 00468 } 00469 00470 00471 if(uip_newdata() || 00472 uip_rexmit() || 00473 uip_acked()) { 00474 vnc_server_send_data(vs); 00475 } else if(uip_poll()) { 00476 ++vs->counter; 00477 /* Abort connection after about 20 seconds of inactivity. */ 00478 if(vs->counter >= 40) { 00479 uip_abort(); 00480 return; 00481 } 00482 00483 vnc_out_poll(vs); 00484 } 00485 00486 } 00487 /*-----------------------------------------------------------------------------------*/