/* ----------------------------------------------------------------------------- * * -------------------------------------------------------------------------- */ static void xtcpd_event(xtcp_event_type_t event, xtcpd_state_t *s) { if (s->linknum != -1) { xtcpd_service_clients_until_ready(s->linknum, xtcp_cons.links, xtcp_cons.nr); xtcpd_send_event(xtcp_cons.links[s->linknum], event, s); } }
void uip_xtcpd_handle_poll(xtcpd_state_t *s) { if (s->s.abort_request) { if (uip_udpconnection()) { uip_udp_conn->lport = 0; xtcpd_event(XTCP_CLOSED, s); } else uip_abort(); s->s.abort_request = 0; } else if (s->s.close_request) { if (uip_udpconnection()) { uip_udp_conn->lport = 0; xtcpd_event(XTCP_CLOSED, s); } else uip_close(); s->s.close_request = 0; } else if (s->s.connect_request) { if (uip_udpconnection()) { xtcpd_init_state(s, XTCP_PROTOCOL_UDP, (unsigned char *) uip_udp_conn->ripaddr, uip_udp_conn->lport, uip_udp_conn->rport, uip_udp_conn); xtcpd_event(XTCP_NEW_CONNECTION, s); s->s.connect_request = 0; } } else if (s->s.send_request) { int len; if (s->linknum != -1) { xtcpd_service_clients_until_ready(s->linknum, xtcp_links, xtcp_num); len = xtcpd_send(xtcp_links[s->linknum], XTCP_REQUEST_DATA, s, uip_appdata, uip_udpconnection() ? XTCP_CLIENT_BUF_SIZE : uip_mss()); uip_send(uip_appdata, len); } s->s.send_request--; } else if (s->s.poll_interval != 0 && timer_expired(&(s->s.tmr))) { xtcpd_event(XTCP_POLL, s); timer_set(&(s->s.tmr), s->s.poll_interval); } }
/* ----------------------------------------------------------------------------- * * -------------------------------------------------------------------------- */ static int do_xtcpd_send(chanend c, xtcp_event_type_t event, xtcpd_state_t *s, unsigned char data[], int mss) { int len; #ifdef XTCP_ENABLE_PARTIAL_PACKET_ACK int outstanding=0; if (!uip_udpconnection()) { if (!s->s.accepts_partial_ack && uip_conn->len > 1) return 0; outstanding = uip_conn->len; if (outstanding == 1) outstanding = 0; s->conn.outstanding = outstanding; } #endif xtcpd_service_clients_until_ready(s->linknum, xtcp_cons.links, xtcp_cons.nr); len = xtcpd_send(c,event,s,data,mss); #ifdef XTCP_ENABLE_PARTIAL_PACKET_ACK if (!uip_udpconnection()) { if (outstanding != 0 && len > outstanding) { len = len - outstanding; memmove((char *) uip_appdata, &((char *)uip_appdata)[outstanding], len); } else if (outstanding > 0) { len = 0; } } #endif return len; }
/* ----------------------------------------------------------------------------- * xtcpd_appcall * * this function is called, when a package comes in for an upper layer * application. * -------------------------------------------------------------------------- */ void xtcpd_appcall(void) { xtcpd_state_t *s; /* --------------- DHCP (v4) --------------- */ if (uip_udpconnection() && (uip_udp_conn->lport == HTONS(DHCPC_CLIENT_PORT) || uip_udp_conn->lport == HTONS(DHCPC_SERVER_PORT))) { #if UIP_USE_DHCP dhcpc_appcall(); #endif return; } /* --------- set up a new connection ---------- */ if (uip_udpconnection()){ s = (xtcpd_state_t *) &(uip_udp_conn->appstate); if (uip_newdata()) { // Set remote port to upper layer state s->conn.remote_port = HTONS(UDPBUF->srcport); uip_ipaddr_copy(s->conn.remote_addr.u8, BUF->srcipaddr.u8); } } else if (uip_conn == NULL) { // dodgy uip_conn return; } else { s = (xtcpd_state_t *) &(uip_conn->appstate); } /* ------ passing new connection event up to the upper xtcp layer ---- */ if (uip_connected()) { if (!uip_udpconnection()) { init_xtcpd_state(s, XTCP_PROTOCOL_TCP, *((xtcp_ipaddr_t *) (&uip_conn->ripaddr)), uip_conn->lport, uip_conn->rport, uip_conn); xtcpd_event(XTCP_NEW_CONNECTION, s); } else { init_xtcpd_state(s, XTCP_PROTOCOL_UDP, *((xtcp_ipaddr_t *) (&uip_udp_conn->ripaddr)), uip_udp_conn->lport, uip_udp_conn->rport, uip_udp_conn); xtcpd_event(XTCP_NEW_CONNECTION, s); } } /* --------------- new data event to deliver --------------- */ if (uip_newdata() && uip_len > 0) { if (s->linknum != -1) { xtcpd_service_clients_until_ready(s->linknum, xtcp_cons.links, xtcp_cons.nr); xtcpd_recv(xtcp_cons.links, s->linknum, xtcp_cons.nr, s, uip_appdata, uip_datalen()); if (!uip_udpconnection() && s->s.ack_recv_mode) { uip_stop(); } } } else if (uip_aborted()) { xtcpd_event(XTCP_ABORTED, s); return; } else if (uip_timedout()) { xtcpd_event(XTCP_TIMED_OUT, s); return; } /* ------------ passing acknowleg event to upper layer ------------- */ if (uip_acked()) { int len; if (s->linknum != -1) { len = do_xtcpd_send(xtcp_cons.links[s->linknum], XTCP_SENT_DATA, s, uip_appdata, uip_udpconnection() ? XTCP_CLIENT_BUF_SIZE : uip_mss()); uip_send(uip_appdata, len); } } /* -------------- retransmit the last package -------------- */ if (uip_rexmit()) { int len; if (s->linknum != -1) { xtcpd_service_clients_until_ready(s->linknum, xtcp_cons.links, xtcp_cons.nr); #ifdef XTCP_ENABLE_PARTIAL_PACKET_ACK s->conn.outstanding = 0; #endif len = xtcpd_send(xtcp_cons.links[s->linknum], XTCP_RESEND_DATA, s, uip_appdata, uip_udpconnection() ? XTCP_CLIENT_BUF_SIZE : uip_mss()); if (len != 0) uip_send(uip_appdata, len); } } /* --------------- poll a connection --------------- */ if (uip_poll()) { uip_xtcpd_handle_poll(s); } #if XTCP_ENABLE_PUSH_FLAG_NOTIFICATION if (uip_tcp_push()) { xtcpd_event(XTCP_PUSH_DATA, s); } #endif /* ------------- connection close event ------------ */ if (uip_closed()) { if (!s->s.closed){ s->s.closed = 1; xtcpd_event(XTCP_CLOSED, s); } return; } }
void xtcpd_appcall(void) { xtcpd_state_t *s; if (uip_udpconnection() && (uip_udp_conn->lport == HTONS(DHCPC_CLIENT_PORT) || uip_udp_conn->lport == HTONS(DHCPC_SERVER_PORT))) { #if UIP_USE_DHCP dhcpc_appcall(); #endif return; } if (uip_udpconnection()) { s = (xtcpd_state_t *) &(uip_udp_conn->appstate); if (uip_newdata()) { s->conn.remote_port = HTONS(UDPBUF->srcport); uip_ipaddr_copy(s->conn.remote_addr, BUF->srcipaddr); } } else if (uip_conn == NULL) { // dodgy uip_conn return; } else s = (xtcpd_state_t *) &(uip_conn->appstate); // if (!uip_udpconnection() && uip_connected()) { if (uip_connected()) { if (!uip_udpconnection()) { xtcpd_init_state(s, XTCP_PROTOCOL_TCP, (unsigned char *) uip_conn->ripaddr, uip_conn->lport, uip_conn->rport, uip_conn); xtcpd_event(XTCP_NEW_CONNECTION, s); } else { xtcpd_init_state(s, XTCP_PROTOCOL_UDP, (unsigned char *) uip_udp_conn->ripaddr, uip_udp_conn->lport, uip_udp_conn->rport, uip_udp_conn); xtcpd_event(XTCP_NEW_CONNECTION, s); } } if (uip_acked()) { int len; if (s->linknum != -1) { xtcpd_service_clients_until_ready(s->linknum, xtcp_links, xtcp_num); len = xtcpd_send(xtcp_links[s->linknum], XTCP_SENT_DATA, s, uip_appdata, uip_udpconnection() ? XTCP_CLIENT_BUF_SIZE : uip_mss()); if (len != 0) uip_send(uip_appdata, len); } } if (uip_newdata() && uip_len > 0) { if (s->linknum != -1) { if (!uip_udpconnection() && s->s.ack_recv_mode) { uip_stop(); } xtcpd_service_clients_until_ready(s->linknum, xtcp_links, xtcp_num); xtcpd_recv(xtcp_links, s->linknum, xtcp_num, s, uip_appdata, uip_datalen()); } } else if (uip_aborted()) { xtcpd_event(XTCP_ABORTED, s); return; } else if (uip_timedout()) { xtcpd_event(XTCP_TIMED_OUT, s); return; } if (uip_rexmit()) { int len; if (s->linknum != -1) { xtcpd_service_clients_until_ready(s->linknum, xtcp_links, xtcp_num); len = xtcpd_send(xtcp_links[s->linknum], XTCP_RESEND_DATA, s, uip_appdata, uip_udpconnection() ? XTCP_CLIENT_BUF_SIZE : uip_mss()); if (len != 0) uip_send(uip_appdata, len); } } if (uip_poll()) { uip_xtcpd_handle_poll(s); } if (uip_closed()) { if (!s->s.closed) { s->s.closed = 1; xtcpd_event(XTCP_CLOSED, s); } return; } }