X-Git-Url: http://git.joshuawise.com/netwatch.git/blobdiff_plain/9eee8073b16fad5359206bb7d832293ce878dd16..779b8ca85ab0f4cc686f9bb3ffe622fef404b99e:/net/rfb.c?ds=inline diff --git a/net/rfb.c b/net/rfb.c index 13f6fb4..e86f03d 100644 --- a/net/rfb.c +++ b/net/rfb.c @@ -2,8 +2,7 @@ #include #include #include - -#include "../aseg-paging/keyboard.h" +#include #include "lwip/tcp.h" #include "lwip/stats.h" @@ -94,7 +93,7 @@ struct update_header { struct rfb_state { enum { - ST_BEGIN, + ST_BEGIN = 0, ST_CLIENTINIT, ST_MAIN } state; @@ -111,7 +110,7 @@ struct rfb_state { struct fb_update_req client_interest_area; enum { - SST_IDLE, + SST_IDLE = 0, SST_HEADER, SST_DATA } send_state; @@ -126,8 +125,11 @@ struct rfb_state { uint32_t chunk_height; uint32_t chunk_lindex; + + uint32_t chunk_checksum; - uint32_t chunk_actually_sent; + int chunk_actually_sent; + int try_in_a_bit; }; static struct server_init_message server_info; @@ -177,7 +179,7 @@ static int advance_chunk(struct rfb_state *state) { state->chunk_ynum = 0; state->send_state = SST_IDLE; if (!(state->chunk_actually_sent)) - state->update_requested = 1; + state->try_in_a_bit = 2; return 1; } @@ -188,7 +190,6 @@ static void send_fsm(struct tcp_pcb *pcb, struct rfb_state *state) { struct update_header hdr; int lines_left; unsigned char * lptr; - uint32_t checksum; int totaldim; err_t err; @@ -236,24 +237,17 @@ static void send_fsm(struct tcp_pcb *pcb, struct rfb_state *state) { state->chunk_height -= (totaldim - fb->curmode.yres); } - outputf("rfb send: (%d [%d], %d [%d]) %d x %d", - state->chunk_xnum, state->chunk_xpos, - state->chunk_ynum, state->chunk_ypos, - state->chunk_width, state->chunk_height); - /* Do we _actually_ need to send this chunk? */ if (fb->checksum_rect) { - checksum = fb->checksum_rect(state->chunk_xpos, state->chunk_ypos, - state->chunk_width, state->chunk_height); + state->chunk_checksum = fb->checksum_rect(state->chunk_xpos, state->chunk_ypos, + state->chunk_width, state->chunk_height); - if (checksum == state->checksums[state->chunk_xnum][state->chunk_ynum]) { - outputf("!!!!!!! SKIPPING: %08x", checksum); + if (state->chunk_checksum == state->checksums[state->chunk_xnum][state->chunk_ynum]) { if (advance_chunk(state)) return; continue; - } else { - state->checksums[state->chunk_xnum][state->chunk_ynum] = checksum; } + /* Checksum gets set in data block, AFTER the data has been sent. */ } outputf("actually sent"); @@ -290,6 +284,7 @@ static void send_fsm(struct tcp_pcb *pcb, struct rfb_state *state) { if (lines_left == 0) { state->send_state = SST_HEADER; + state->checksums[state->chunk_xnum][state->chunk_ynum] = state->chunk_checksum; if (advance_chunk(state)) return; break; @@ -333,6 +328,12 @@ static err_t rfb_sent(void *arg, struct tcp_pcb *pcb, uint16_t len) { static err_t rfb_poll(void *arg, struct tcp_pcb *pcb) { struct rfb_state *state = arg; send_fsm(pcb, state); + if (state->try_in_a_bit) { + state->try_in_a_bit--; + if (!(state->try_in_a_bit)) { + state->update_requested = 1; + } + } /* stats_display(); */ @@ -340,11 +341,13 @@ static err_t rfb_poll(void *arg, struct tcp_pcb *pcb) { } static void close_conn(struct tcp_pcb *pcb, struct rfb_state *state) { + outputf("close_conn: bailing"); tcp_arg(pcb, NULL); tcp_sent(pcb, NULL); tcp_recv(pcb, NULL); mem_free(state); tcp_close(pcb); + outputf("close_conn: done"); } enum fsm_result { @@ -507,6 +510,7 @@ static enum fsm_result recv_fsm(struct tcp_pcb *pcb, struct rfb_state *state) { default: outputf("RFB: Bad command: %d", state->data[0]); + return FAIL; } default: outputf("RFB: Bad state"); @@ -517,6 +521,7 @@ static enum fsm_result recv_fsm(struct tcp_pcb *pcb, struct rfb_state *state) { static err_t rfb_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) { struct rfb_state *state = arg; + uint16_t copylen; if (state == NULL) @@ -539,8 +544,8 @@ static err_t rfb_recv(void *arg, struct tcp_pcb *pcb, return ERR_OK; } - outputf("RFB: Processing %d", p->tot_len); - pbuf_copy_partial(p, state->data + state->writepos, p->tot_len, 0); + copylen = pbuf_copy_partial(p, state->data + state->writepos, p->tot_len, 0); + outputf("RFB: Processing %d, wp %d, cp %d", p->tot_len, state->writepos, copylen); state->writepos += p->tot_len; tcp_recved(pcb, p->tot_len); @@ -550,26 +555,21 @@ static err_t rfb_recv(void *arg, struct tcp_pcb *pcb, switch (recv_fsm(pcb, state)) { case NEEDMORE: outputf("RFB FSM: blocking"); - /* Need more data */ - return ERR_OK; + goto doneprocessing; case OK: outputf("RFB FSM: ok"); - /* Kick off a send. */ - if (state->send_state == SST_IDLE - && state->update_requested) { - send_fsm(pcb, state); - } - if (state->readpos == state->writepos) { state->readpos = 0; state->writepos = 0; - return ERR_OK; + goto doneprocessing; } else { memmove(state->data, state->data + state->readpos, state->writepos - state->readpos); + state->writepos -= state->readpos; + state->readpos = 0; } break; case FAIL: @@ -579,6 +579,15 @@ static err_t rfb_recv(void *arg, struct tcp_pcb *pcb, return ERR_OK; } } + +doneprocessing: + + /* Kick off a send. */ + if (state->send_state == SST_IDLE && state->update_requested) { + send_fsm(pcb, state); + } + + return ERR_OK; } static err_t rfb_accept(void *arg, struct tcp_pcb *pcb, err_t err) { @@ -589,14 +598,10 @@ static err_t rfb_accept(void *arg, struct tcp_pcb *pcb, err_t err) { state = (struct rfb_state *)mem_malloc(sizeof(struct rfb_state)); + memset(state, 0, sizeof(struct rfb_state)); + state->state = ST_BEGIN; - state->readpos = 0; - state->writepos = 0; - state->update_requested = 0; state->send_state = SST_IDLE; - state->chunk_xnum = 0; - state->chunk_ynum = 0; - memset(state->checksums, 0, sizeof(state->checksums)); /* XXX: update_server_info() should be called from the 64ms timer, and deal * with screen resizes appropriately. */