Exemple #1
0
err_t process_packet_FPV_tcp_recv(struct tcp_pcb * pcb, struct pbuf * pbuf,
		     err_t err) {
	struct pbuf * p = pbuf;

	if (p == NULL) {
		return close_conn(pcb, CONNCLOSED_USER, ERR_OK);
	}

	while (p) {
		int data_left = p->len;
		uint8_t *data_ptr = p->payload;
		int fsar = 0;

		if (ps_buffered) {
			/* There's some leftover data from the last pbuf that
			 * we processed, so copy it in first. */
			int more = PS_BUFFER_SIZE - ps_buffered;
			if (more > data_left)
				more = data_left;

			ASSERT_NOT_EQUAL(more, 0);

			memcpy(ps_buffer + ps_buffered, data_ptr, more);

			fsar = recv_fsm(pcb, ps_buffer, ps_buffered + more);

			/* We still may not yet have enough. This should only
			 * happen becuase we're out of data in this pbuf, not
			 * because we couldn't fit it all in ps_buffer. */
			if (fsar == 0) {
				ASSERT_EQUAL(data_left, more);
				data_ptr += more;
				data_left -= more;
				ps_buffered += more;
			} else if (fsar < 0) {
				break;
			} else {
				/* Now, depending on the command, we may not
				 * have needed *all* PS_BUFFER_SIZE bytes. The
				 * *next* command, however, should start in
				 * the pbuf - if not, something's wrong, since
				 * we should have processed the previous
				 * command before now. */
				ASSERT(fsar > ps_buffered);

				/* Consume only what we actually used from the
				 * buffer, so that the next recv_fsm call can
				 * point directly at the buffer. */
				data_ptr += (fsar - ps_buffered);
				data_left -= (fsar - ps_buffered);
				ps_buffered = 0;
			}
		}

		/* At this point, there should be no more buffered data. */
		if (data_left)
			ASSERT_EQUAL(ps_buffered, 0);

		/* Now that we've dealt with playing out anything that was
		 * buffered with a previous pbuf, let's deal with this one. */
		while (data_left) {
			fsar = recv_fsm(pcb, data_ptr, data_left);

			if (fsar == 0) {
				/* There isn't enough. */
				ASSERT(data_left < PS_BUFFER_SIZE);
				memcpy(ps_buffer, data_ptr, data_left);
				ps_buffered = data_left;
				data_left = 0;
			} else if (fsar < 0) {
				break;
			} else {
				data_ptr += fsar;
				data_left -= fsar;
			}
		}

		if (fsar < 0)
			break;

		/* Move on to the next pbuf. */
		p = p->next;
	}

	ps_send_deferred_acks(pcb);

	/* Tell lwIP we're done with this packet. */
	tcp_recved(pcb, pbuf->tot_len);
	pbuf_free(pbuf);

	return ERR_OK;
}
Exemple #2
0
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) 

	if (err != ERR_OK) {
		outputf("RFB: recv err %d", err);
		/* FIXME do something better here? */
		return ERR_OK;
	}

	if (p == NULL) {
		outputf("RFB: Connection closed");
		close_conn(pcb, state);
		return ERR_OK;
	}

	if (p->tot_len > (RFB_BUF_SIZE - state->writepos)) {
		/* Overflow! */
		outputf("RFB: Overflow!");
		close_conn(pcb, state);
		return ERR_OK;
	}

	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);
	pbuf_free(p);

	while (1) {
		switch (recv_fsm(pcb, state)) {
		case NEEDMORE:
			outputf("RFB FSM: blocking");
			goto doneprocessing;

		case OK:
			if (state->readpos == state->writepos) {
				state->readpos = 0;
				state->writepos = 0;
				goto doneprocessing;
			} else {
				memmove(state->data,
					state->data + state->readpos,
					state->writepos - state->readpos);
				state->writepos -= state->readpos;
				state->readpos = 0;
			}
			break;
		case FAIL:
			/* Shit */
			outputf("RFB: Protocol error");
			close_conn(pcb, state);
			return ERR_OK;
		}
	}

doneprocessing:

	/* Kick off a send. */
	if (state->send_state == SST_IDLE && state->update_requested) {
		send_fsm(pcb, state);
	}

	return ERR_OK;
}