/*---------------------------------------------------------------------------*/ void httpd_appcall(void *state) { struct httpd_state *s = (struct httpd_state *)state; if(uip_closed() || uip_aborted() || uip_timedout()) { if(s != NULL) { memb_free(&conns, s); } } else if(uip_connected()) { s = (struct httpd_state *)memb_alloc(&conns); if(s == NULL) { uip_abort(); return; } tcp_markconn(uip_conn, s); PSOCK_INIT(&s->sin, s->inputbuf, sizeof(s->inputbuf) - 1); PSOCK_INIT(&s->sout, s->inputbuf, sizeof(s->inputbuf) - 1); PT_INIT(&s->outputpt); s->state = STATE_WAITING; timer_set(&s->timer, CLOCK_SECOND * 10); handle_connection(s); } else if(s != NULL) { if(uip_poll()) { if(timer_expired(&s->timer)) { uip_abort(); } } else { timer_reset(&s->timer); } handle_connection(s); } else { uip_abort(); } }
/*---------------------------------------------------------------------------*/ void httpd_appcall(void) { struct httpd_state *s = (struct httpd_state *)&(uip_conn->appstate); if(uip_closed() || uip_aborted() || uip_timedout()) { } else if(uip_connected()) { PSOCK_INIT(&s->sin, s->inputbuf, sizeof(s->inputbuf) - 1); PSOCK_INIT(&s->sout, s->inputbuf, sizeof(s->inputbuf) - 1); PT_INIT(&s->outputpt); s->state = STATE_WAITING; /* timer_set(&s->timer, CLOCK_SECOND * 100);*/ s->timer = 0; handle_connection(s); } else if(s != NULL) { if(uip_poll()) { ++s->timer; if(s->timer >= 20) { uip_abort(); } } else { s->timer = 0; } handle_connection(s); } else { uip_abort(); } }
/*-----------------------------------------------------------------------------------*/ void webclient_appcall(void) { if(uip_connected()) { s.timer = 0; s.state = WEBCLIENT_STATE_STATUSLINE; senddata(); webclient_connected(); return; } if(s.state == WEBCLIENT_STATE_CLOSE) { webclient_closed(); uip_abort(); return; } if(uip_aborted()) { webclient_aborted(); } if(uip_timedout()) { webclient_timedout(); } if(uip_acked()) { s.timer = 0; acked(); } if(uip_newdata()) { s.timer = 0; newdata(); } if(uip_rexmit() || uip_newdata() || uip_acked()) { senddata(); } else if(uip_poll()) { ++s.timer; if(s.timer == WEBCLIENT_TIMEOUT) { webclient_timedout(); uip_abort(); return; } /* senddata();*/ } if(uip_closed()) { if(s.httpflag != HTTPFLAG_MOVED) { /* Send NULL data to signal EOF. */ webclient_datahandler(NULL, 0); } else { if(resolv_lookup(s.host) == NULL) { resolv_query(s.host); } webclient_get(s.host, s.port, s.file); } } }
/* identify_data(): * * This function looks at the state of the connection (i.e., if it is * handshaking or in steady-state) as well as on the contents of the * incoming message and returns the number of bytes of data that is to * be expected. */ static uint16_t identify_data(CC_REGISTER_ARG uint8_t *data, uint16_t datalen) { switch(vs->waitmsg) { case VNC_WAIT_VERSION: /* Expecting version string (12 bytes). */ return 12; break; case VNC_WAIT_AUTH: return 4; break; case VNC_WAIT_AUTH_RESPONSE: return 1; break; case VNC_WAIT_SINIT: /* XXX: We should check that the entire message header is received, otherwise we should buffer it. */ return sizeof(struct rfb_server_init) + ((struct rfb_server_init *)uip_appdata)->namelength[3] + ((struct rfb_server_init *)uip_appdata)->namelength[2]; case VNC_WAIT_UPDATE: case VNC_WAIT_NONE: switch(*data) { case RFB_FB_UPDATE: PRINTF(("RFB FB UPDATE received\n")); return sizeof(struct rfb_fb_update); case RFB_BELL: return 1; case RFB_SERVER_CUT_TEXT: PRINTF(("Cut text received, unhandled\n")); return 8 + (data[6] << 8) + data[7]; case RFB_SET_COLORMAP_ENTRIES: uip_abort(); PRINTF(("Set colormap entries received, unhandled\n")); return 0; default: uip_abort(); PRINTF(("Weird message type received (%d)\n", *(uint8_t *)uip_appdata)); return 0; } break; case VNC_WAIT_UPDATE_RECT: return sizeof(struct rfb_fb_update_rect_hdr); default: PRINTF(("identify: bad waitmsg %d\n", vs->waitmsg)); } return 0; }
/* next_sciptstate: * * Reads one line of script and decides what to do next. */ static void next_scriptstate(void) { struct httpd_fs_file fsfile; u8_t i; again: switch(hs->script[0]) { case ISO_t: /* Send a text string. */ hs->state = HTTP_TEXT; hs->dataptr = &hs->script[2]; /* Calculate length of string. */ for(i = 0; hs->dataptr[i] != ISO_nl; ++i); hs->count = i; break; case ISO_c: /* Call a function. */ hs->state = HTTP_FUNC; hs->dataptr = NULL; hs->count = 0; uip_reset_acked(); break; case ISO_i: /* Include a file. */ hs->state = HTTP_FILE; if(!httpd_fs_open(&hs->script[2], &fsfile)) { uip_abort(); dealloc_state(hs); } hs->dataptr = fsfile.data; hs->count = fsfile.len; break; case ISO_hash: /* Comment line. */ next_scriptline(); goto again; break; case ISO_period: /* End of script. */ hs->state = HTTP_END; uip_close(); dealloc_state(hs); break; default: uip_abort(); dealloc_state(hs); break; } }
/*---------------------------------------------------------------------------*/ void httpd_appcall(void *state) { #if DEBUGLOGIC struct httpd_state *s; //Enter here for debugging with output directed to TCPBUF s = sg = (struct httpd_state *)memb_alloc(&conns); if (1) { #else struct httpd_state *s = (struct httpd_state *)state; if(uip_closed() || uip_aborted() || uip_timedout()) { if(s != NULL) { memb_free(&conns, s); } } else if(uip_connected()) { s = (struct httpd_state *)memb_alloc(&conns); if(s == NULL) { uip_abort(); return; } #endif tcp_markconn(uip_conn, s); PSOCK_INIT(&s->sin, (uint8_t *)s->inputbuf, sizeof(s->inputbuf) - 1); PSOCK_INIT(&s->sout, (uint8_t *)s->inputbuf, sizeof(s->inputbuf) - 1); PT_INIT(&s->outputpt); s->state = STATE_WAITING; /* timer_set(&s->timer, CLOCK_SECOND * 100);*/ s->timer = 0; handle_connection(s); } else if(s != NULL) { if(uip_poll()) { ++s->timer; if(s->timer >= 20) { uip_abort(); memb_free(&conns, s); } } else { s->timer = 0; } handle_connection(s); } else { uip_abort(); } } /*---------------------------------------------------------------------------*/ void httpd_init(void) { tcp_listen(UIP_HTONS(80)); memb_init(&conns); httpd_cgi_init(); }
/****************************************************************************** * void exosite_appcall(void) * * This function is uIP's application function. It is called whenever a uIP * event occurs (e.g. when a new connection is established, new data arrives, * sent data is acknowledged, data needs to be retransmitted, etc.). * ******************************************************************************/ void exosite_appcall(void) { if(uip_connected()) { s.timer = 0; senddata(); return; } if(s.state == EXO_STATE_CLOSE) { uip_abort(); return; } if(uip_aborted()) { } if(uip_timedout()) { } if(uip_acked()) { s.timer = 0; acked(); } if(uip_newdata()) { s.timer = 0; newdata(); } if(uip_rexmit() || uip_newdata() || uip_acked()) { senddata(); } else if(uip_poll()) { ++s.timer; if(s.timer == EXO_TIMEOUT) { uip_abort(); return; } } #if 0 if(uip_closed()) { if(s.httpflag != HTTPFLAG_MOVED) { memset(s.rxdata,0,sizeof(s.rxdata)); } else { if(resolv_lookup(s.host) == NULL) { resolv_query(s.host); } } } #endif }
/*---------------------------------------------------------------------------*/ static PT_THREAD(handle_output(struct httpd_state *s)) { PT_BEGIN(&s->outputpt); s->fd = cfs_open(s->filename, CFS_READ); if(s->fd < 0) { s->fd = cfs_open("404.html", CFS_READ); if(s->fd < 0) { uip_abort(); PT_EXIT(&s->outputpt); } PT_WAIT_THREAD(&s->outputpt, send_headers(s, "HTTP/1.0 404 Not found\r\n")); PT_WAIT_THREAD(&s->outputpt, send_file(s)); } else { PT_WAIT_THREAD(&s->outputpt, send_headers(s, "HTTP/1.0 200 OK\r\n")); PT_WAIT_THREAD(&s->outputpt, send_file(s)); cfs_close(s->fd); } PSOCK_CLOSE(&s->sout); PT_END(&s->outputpt); }
/* webclient_datahandler(): * * Callback function. Called from the webclient module when HTTP data * has arrived. */ void webclient_datahandler(char *data, u16_t len) { if(len > 0) { if(strcmp(webclient_mimetype(), http_texthtml) == 0) { count = (count + 1) & 3; show_statustext(receivingmsgs[count]); htmlparser_parse(data, len); redraw_window(); } else { uip_abort(); #if WWW_CONF_WITH_WGET ctk_dialog_open(&wgetdialog); #endif /* WWW_CONF_WITH_WGET */ } } else { /* Clear remaining parts of page. */ loading = 0; } if(data == NULL) { loading = 0; show_statustext("Done."); petsciiconv_topetscii(&webpage[(WWW_CONF_WEBPAGE_HEIGHT - 1) * WWW_CONF_WEBPAGE_WIDTH], WWW_CONF_WEBPAGE_WIDTH); CTK_WIDGET_FOCUS(&mainwindow, &urlentry); redraw_window(); } }
/*---------------------------------------------------------------------*/ PROCESS_THREAD(tcp_loader_process, ev, data) { PROCESS_BEGIN(); tcp_listen(HTONS(CODEPROP_DATA_PORT)); while(1) { PROCESS_YIELD(); if(ev == tcpip_event && uip_conn->lport == HTONS(CODEPROP_DATA_PORT)) { if(uip_connected()) { /* Really uip_connecting()!!! */ if(data == NULL) { PT_INIT(&s.tcpthread_pt); process_poll(&tcp_loader_process); tcp_markconn(uip_conn, &s); } else { PRINTF(("codeprop: uip_connected() and data != NULL\n")); uip_abort(); } } recv_tcpthread(&s.tcpthread_pt); /* Run thread */ if(uip_closed() || uip_aborted() || uip_timedout()) { PRINTF(("codeprop: connection down\n")); tcp_markconn(uip_conn, NULL); } } } PROCESS_END(); }
/*---------------------------------------------------------------------*/ static void uipcall(void *state) { if(uip_udpconnection()) { recv_udpthread(&s.recv_udpthread_pt); send_udpthread(&s.udpthread_pt); } else { if(uip_conn->lport == HTONS(CODEPROP_DATA_PORT)) { if(uip_connected()) { if(state == NULL) { s.addr = 0; s.count = 0; PT_INIT(&s.tcpthread_pt); process_poll(&codeprop_process); tcp_markconn(uip_conn, &s); /* process_post(PROCESS_BROADCAST, codeprop_event_quit, */ /* (process_data_t)NULL); */ } else { PRINTF(("codeprop: uip_connected() and state != NULL\n")); uip_abort(); } } recv_tcpthread(&s.tcpthread_pt); if(uip_closed() || uip_aborted() || uip_timedout()) { PRINTF(("codeprop: connection down\n")); tcp_markconn(uip_conn, NULL); } } } }
/*---------------------------------------------------------------------------*/ static PT_THREAD(handle_output(struct httpd_state *s)) { PT_BEGIN(&s->outputpt); petsciiconv_topetscii(s->filename, sizeof(s->filename)); s->fd = cfs_open(s->filename, CFS_READ); petsciiconv_toascii(s->filename, sizeof(s->filename)); if(s->fd < 0) { s->fd = cfs_open("notfound.html", CFS_READ); if(s->fd < 0) { uip_abort(); memb_free(&conns, s); webserver_log_file(&uip_conn->ripaddr, "reset (no notfound.html)"); PT_EXIT(&s->outputpt); } PT_WAIT_THREAD(&s->outputpt, send_headers(s, http_header_404)); } else { PT_WAIT_THREAD(&s->outputpt, send_headers(s, http_header_200)); } PT_WAIT_THREAD(&s->outputpt, send_file(s)); cfs_close(s->fd); s->fd = -1; PSOCK_CLOSE(&s->sout); PT_END(&s->outputpt); }
static inline void mqtt_abort_connection(void) { uip_abort(); mqtt_uip_conn = NULL; mqtt_fire_close_callback(); }
/*---------------------------------------------------------------------------*/ static void acked(struct tcp_socket *s) { if(s->output_senddata_len > 0) { /* Copy the data in the outputbuf down and update outputbufptr and outputbuf_lastsent */ if(s->output_data_send_nxt > 0) { memcpy(&s->output_data_ptr[0], &s->output_data_ptr[s->output_data_send_nxt], s->output_data_maxlen - s->output_data_send_nxt); } if(s->output_data_len < s->output_data_send_nxt) { printf("tcp: acked assertion failed s->output_data_len (%d) < s->output_data_send_nxt (%d)\n", s->output_data_len, s->output_data_send_nxt); tcp_markconn(uip_conn, NULL); uip_abort(); call_event(s, TCP_SOCKET_ABORTED); relisten(s); return; } s->output_data_len -= s->output_data_send_nxt; s->output_senddata_len = s->output_data_len; s->output_data_send_nxt = 0; call_event(s, TCP_SOCKET_DATA_SENT); } }
/*---------------------------------------------------------------------------*/ void httpd_appcall(void *state) { struct httpd_state *s = (struct httpd_state *)state; if(uip_closed() || uip_aborted() || uip_timedout()) { if(s != NULL) { if(s->fd >= 0) { cfs_close(s->fd); s->fd = -1; } memb_free(&conns, s); } } else if(uip_connected()) { s = (struct httpd_state *)memb_alloc(&conns); if(s == NULL) { uip_abort(); webserver_log_file(&uip_conn->ripaddr, "reset (no memory block)"); return; } tcp_markconn(uip_conn, s); PSOCK_INIT(&s->sin, (uint8_t *)s->inputbuf, sizeof(s->inputbuf) - 1); PSOCK_INIT(&s->sout, (uint8_t *)s->inputbuf, sizeof(s->inputbuf) - 1); PT_INIT(&s->outputpt); s->fd = -1; s->state = STATE_WAITING; timer_set(&s->timer, CLOCK_SECOND * 10); handle_connection(s); } else if(s != NULL) { if(uip_poll()) { if(timer_expired(&s->timer)) { uip_abort(); if(s->fd >= 0) { cfs_close(s->fd); s->fd = -1; } memb_free(&conns, s); webserver_log_file(&uip_conn->ripaddr, "reset (timeout)"); } } else { timer_restart(&s->timer); } handle_connection(s); } else { uip_abort(); } }
/*-----------------------------------------------------------------------------------*/ void vnc_server_appcall(struct vnc_server_state *vs) { vs->type = uip_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); } }
/*-----------------------------------------------------------------------------------*/ static void newdata(void) { if(*(char *)uip_appdata == ISO_5) { smtp_done(1); uip_abort(); return; } /* printf("Got %d bytes: '%s'\n", uip_datalen(), uip_appdata);*/ switch(s.state) { case STATE_SEND_NONE: if(strncmp((char *)uip_appdata, smtp_220, 3) == 0) { /* printf("Newdata(): SEND_NONE, got 220, towards SEND_HELO\n");*/ s.state = STATE_SEND_HELO; s.sendptr = 0; } break; case STATE_SEND_HELO: if(*(char *)uip_appdata == ISO_2) { /* printf("Newdata(): SEND_HELO, got 2*, towards SEND_MAIL_FROM\n");*/ s.state = STATE_SEND_MAIL_FROM; s.sendptr = 0; } break; case STATE_SEND_MAIL_FROM: if(*(char *)uip_appdata == ISO_2) { /* printf("Newdata(): SEND_MAIL_FROM, got 2*, towards SEND_RCPT_TO\n"); */ /* printf("2\n");*/ s.state = STATE_SEND_RCPT_TO; s.textlen = s.sendptr = 0; } break; case STATE_SEND_RCPT_TO: if(*(char *)uip_appdata == ISO_2) { /* printf("2\n");*/ s.state = STATE_SEND_DATA; s.textlen = s.sendptr = 0; } break; case STATE_SEND_DATA: if(*(char *)uip_appdata == ISO_3) { /* printf("3\n");*/ s.state = STATE_SEND_DATA_HEADERS; s.textlen = s.sendptr = 0; } break; case STATE_SEND_DATA_HEADERS: if(*(char *)uip_appdata == ISO_3) { /* printf("3\n");*/ s.state = STATE_SEND_DATA_MESSAGE; s.textlen = s.sendptr = 0; } break; } }
/*---------------------------------------------------------------------*/ static PT_THREAD(recv_tcpthread(struct pt *pt)) { PT_BEGIN(pt); /* Read the header. */ PT_WAIT_UNTIL(pt, uip_newdata() && uip_datalen() > 0); if(uip_datalen() < sizeof(struct codeprop_tcphdr)) { PRINTF(("codeprop: header not found in first tcp segment\n")); uip_abort(); goto thread_done; } s.len = uip_htons(((struct codeprop_tcphdr *)uip_appdata)->len); s.addr = 0; uip_appdata += sizeof(struct codeprop_tcphdr); uip_len -= sizeof(struct codeprop_tcphdr); xmem_erase(XMEM_ERASE_UNIT_SIZE, EEPROMFS_ADDR_CODEPROP); /* Read the rest of the data. */ do { if(uip_len > 0) { xmem_pwrite(uip_appdata, uip_len, EEPROMFS_ADDR_CODEPROP + s.addr); s.addr += uip_len; } if(s.addr < s.len) { PT_YIELD_UNTIL(pt, uip_newdata()); } } while(s.addr < s.len); /* Kill old program. */ elfloader_unload(); /* Link, load, and start new program. */ int s; static char msg[30 + 10]; s = elfloader_load(EEPROMFS_ADDR_CODEPROP); if (s == ELFLOADER_OK) sprintf(msg, "ok\n"); else sprintf(msg, "err %d %s\n", s, elfloader_unknown); /* Return "ok" message. */ do { s = strlen(msg); uip_send(msg, s); PT_WAIT_UNTIL(pt, uip_acked() || uip_rexmit() || uip_closed()); } while(uip_rexmit()); /* Close the connection. */ uip_close(); thread_done:; PT_END(pt); }
/* ----------------------------------------------------------------------------- * * -------------------------------------------------------------------------- */ static void uip_xtcpd_handle_poll(xtcpd_state_t *s) { if (s->s.ack_request) { uip_flags |= UIP_NEWDATA; uip_slen = 0; s->s.ack_request = 0; } 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()) { 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); s->s.connect_request = 0; } } else if (s->s.send_request) { /* ----------------------------------- */ int len; if (s->linknum != -1) { len = do_xtcpd_send(xtcp_cons.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 u16_t parse_statusline(u16_t len) * * Parses the status line of a HTTP response * ******************************************************************************/ static u16_t parse_statusline(u16_t len) { char *cptr; while(len > 0 && s.httpheaderlineptr < sizeof(s.httpheaderline)) { s.httpheaderline[s.httpheaderlineptr] = *(char *)uip_appdata; ++((char *)uip_appdata); --len; if(s.httpheaderline[s.httpheaderlineptr] == ISO_nl) { if((strncmp(s.httpheaderline, http_10, sizeof(http_10) - 1) == 0) || (strncmp(s.httpheaderline, http_11, sizeof(http_11) - 1) == 0)) { cptr = &(s.httpheaderline[9]); s.httpflag = HTTPFLAG_NONE; if(strncmp(cptr, http_200, sizeof(http_200) - 1) == 0) { /* 200 OK */ s.httpflag = HTTPFLAG_OK; } else if(strncmp(cptr, http_301, sizeof(http_301) - 1) == 0 || strncmp(cptr, http_302, sizeof(http_302) - 1) == 0) { /* 301 Moved permanently or 302 Found. Location: header line will contain thw new location. */ s.httpflag = HTTPFLAG_MOVED; } else if(strncmp(cptr, "401 Unauthorized", sizeof("401 Unauthorized") - 1) == 0 ) { s.state = EXO_STATE_NEEDS_META; uip_abort(); return 0; } else { s.httpheaderline[s.httpheaderlineptr - 1] = 0; } } else { uip_abort(); // webclient_aborted(); return 0; } /* We're done parsing the status line, so we reset the pointer and start parsing the HTTP headers.*/ s.httpheaderlineptr = 0; s.state = EXO_STATE_HEADERS; break; } else { ++s.httpheaderlineptr; } } return len; }
/*-----------------------------------------------------------------------------------*/ static u16_t parse_statusline(u16_t len) { char *cptr; char *ku = (char *) uip_appdata; //printf("%s() masuk, len: %d\r\n", __FUNCTION__, len); while(len > 0 && s.httpheaderlineptr < sizeof(s.httpheaderline)) { //s.httpheaderline[s.httpheaderlineptr] = *(char *)uip_appdata; //++((char *)uip_appdata); //++uip_appdata; s.httpheaderline[s.httpheaderlineptr] = *ku; ++(char *)ku; --len; if(s.httpheaderline[s.httpheaderlineptr] == ISO_nl) { if((strncmp(s.httpheaderline, http_10, sizeof(http_10) - 1) == 0) || (strncmp(s.httpheaderline, http_11, sizeof(http_11) - 1) == 0)) { cptr = &(s.httpheaderline[9]); s.httpflag = HTTPFLAG_NONE; if(strncmp(cptr, http_200, sizeof(http_200) - 1) == 0) { /* 200 OK */ s.httpflag = HTTPFLAG_OK; } else if(strncmp(cptr, http_301, sizeof(http_301) - 1) == 0 || strncmp(cptr, http_302, sizeof(http_302) - 1) == 0) { /* 301 Moved permanently or 302 Found. Location: header line will contain thw new location. */ s.httpflag = HTTPFLAG_MOVED; } else { s.httpheaderline[s.httpheaderlineptr - 1] = 0; } } else { uip_abort(); //webclient_aborted(); //printf("%s(): Aborted\r\n", __FUNCTION__); return 0; } /* We're done parsing the status line, so we reset the pointer and start parsing the HTTP headers.*/ s.httpheaderlineptr = 0; s.state = WEBCLIENT_STATE_HEADERS; break; } else { ++s.httpheaderlineptr; } } return len; }
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 u16_t parse_statusline(u16_t len) { char *cptr; char* temp; while(len > 0 && s.httpheaderlineptr < sizeof(s.httpheaderline)) { s.httpheaderline[s.httpheaderlineptr] = *(char *)uip_appdata; //((char *)uip_appdata)++; temp = (char *)uip_appdata; temp++; uip_appdata = temp; --len; if(s.httpheaderline[s.httpheaderlineptr] == ISO_nl) { if((strncmp(s.httpheaderline, http_11,sizeof(http_11) - 1) == 0)) { cptr = &(s.httpheaderline[9]); s.httpflag = HTTPFLAG_NONE; if(strncmp(cptr, http_200, sizeof(http_200) - 1) == 0) { /* 200 OK */ s.httpflag = HTTPFLAG_OK; } else if(strncmp(cptr, http_301, sizeof(http_301) - 1) == 0 || strncmp(cptr, http_302, sizeof(http_302) - 1) == 0) { /* 301 Moved permanently or 302 Found. Location: header line * will contain the new location. */ s.httpflag = HTTPFLAG_MOVED; } else { s.httpheaderline[s.httpheaderlineptr - 1] = 0; } } else { uip_abort(); webclient_aborted(); return 0; } /* We're done parsing the status line, so we reset the pointer * and start parsing the HTTP headers.*/ s.httpheaderlineptr = 0; s.state = WEBCLIENT_STATE_HEADERS; break; } else { ++s.httpheaderlineptr; } } return len; }
/** HTTP Server State handler for the Request Process state. This state manages the processing of incoming HTTP * GET requests to the server from the receiving HTTP client. */ static void HTTPServerApp_OpenRequestedFile(void) { uip_tcp_appstate_t* const AppState = &uip_conn->appstate; char* const AppData = (char*)uip_appdata; /* No HTTP header received from the client, abort processing */ if (!(uip_newdata())) return; char* RequestToken = strtok(AppData, " "); char* RequestedFileName = strtok(NULL, " "); /* Must be a GET request, abort otherwise */ if (strcmp(RequestToken, "GET") != 0) { uip_abort(); return; } /* Copy over the requested filename */ strncpy(AppState->HTTPServer.FileName, &RequestedFileName[1], (sizeof(AppState->HTTPServer.FileName) - 1)); /* Ensure filename is null-terminated */ AppState->HTTPServer.FileName[sizeof(AppState->HTTPServer.FileName) - 1] = 0x00; /* Determine the length of the URI so that it can be checked to see if it is a directory */ uint8_t FileNameLen = strlen(AppState->HTTPServer.FileName); /* If the URI is a directory, append the default filename */ if (AppState->HTTPServer.FileName[FileNameLen - 1] == '/') { strncpy_P(&AppState->HTTPServer.FileName[FileNameLen], DefaultDirFileName, (sizeof(AppState->HTTPServer.FileName) - FileNameLen)); /* Ensure altered filename is still null-terminated */ AppState->HTTPServer.FileName[sizeof(AppState->HTTPServer.FileName) - 1] = 0x00; } /* Try to open the file from the Dataflash disk */ AppState->HTTPServer.FileOpen = (f_open(&AppState->HTTPServer.FileHandle, AppState->HTTPServer.FileName, (FA_OPEN_EXISTING | FA_READ)) == FR_OK); /* Lock to the SendResponseHeader state until connection terminated */ AppState->HTTPServer.CurrentState = WEBSERVER_STATE_SendResponseHeader; AppState->HTTPServer.NextState = WEBSERVER_STATE_SendResponseHeader; }
/*-----------------------------------------------------------------------------------*/ void telnet_app(void *ts) { struct telnet_state *s = (struct telnet_state *)ts; if(uip_connected()) { s->flags = 0; telnet_connected(s); senddata(s); return; } if(uip_closed()) { telnet_closed(s); } if(uip_aborted()) { telnet_aborted(s); } if(uip_timedout()) { telnet_timedout(s); } if(s->flags & FLAG_CLOSE) { uip_close(); return; } if(s->flags & FLAG_ABORT) { uip_abort(); return; } if(uip_acked()) { acked(s); } if(uip_newdata()) { telnet_newdata(s, (char *)uip_appdata, uip_datalen()); } if(uip_rexmit() || uip_newdata() || uip_acked()) { senddata(s); } else if(uip_poll()) { senddata(s); } }
/*-----------------------------------------------------------------------------------*/ static uint16_t parse_statusline(struct websocket_http_client_state *s, uint16_t len) { uint8_t *cptr; while(len > 0 && s->inputbufptr < sizeof(s->inputbuf)) { s->inputbuf[s->inputbufptr] = *(char *)uip_appdata; uip_appdata = (char *)uip_appdata + 1; --len; if(s->inputbuf[s->inputbufptr] == ISO_nl) { if((strncmp(s->inputbuf, http_10, sizeof(http_10) - 1) == 0) || (strncmp(s->inputbuf, http_11, sizeof(http_11) - 1) == 0)) { cptr = &(s->inputbuf[9]); s->httpflag = HTTPFLAG_NONE; if(strncmp(cptr, http_200, sizeof(http_200) - 1) == 0) { /* 200 OK */ s->httpflag = HTTPFLAG_OK; } else if(strncmp(cptr, http_301, sizeof(http_301) - 1) == 0 || strncmp(cptr, http_302, sizeof(http_302) - 1) == 0) { /* 301 Moved permanently or 302 Found. Location: header line will contain thw new location. */ s->httpflag = HTTPFLAG_MOVED; } else { s->inputbuf[s->inputbufptr - 1] = 0; } } else { uip_abort(); websocket_http_client_aborted(s); return 0; } /* We're done parsing the status line, so we reset the pointer and start parsing the HTTP headers.*/ s->inputbufptr = 0; s->state = WEBSOCKET_HTTP_CLIENT_STATE_HEADERS; break; } else { ++s->inputbufptr; } } return len; }
void httpd_handle_vfs_send_body (void) { vfs_fseek (STATE->u.vfs.fd, STATE->u.vfs.acked, SEEK_SET); vfs_size_t len = vfs_read (STATE->u.vfs.fd, uip_appdata, uip_mss ()); if (len <= 0) { uip_abort (); httpd_cleanup (); return; } if (len < uip_mss ()) /* Short read -> EOF */ STATE->eof = 1; STATE->u.vfs.sent = STATE->u.vfs.acked + len; uip_send (uip_appdata, len); }
/*---------------------------------------------------------------------*/ PROCESS_THREAD(tcp_loader_process, ev, data) { PROCESS_BEGIN(); rudolph0_open(&rudolph0, 20, &rudolph0_call); tcp_listen(HTONS(CODEPROP_DATA_PORT)); while(1) { PROCESS_YIELD(); if(ev == tcpip_event && uip_conn->lport == HTONS(CODEPROP_DATA_PORT)) { if(uip_connected()) { /* Really uip_connecting()!!! */ if(data == NULL) { PT_INIT(&s.tcpthread_pt); process_poll(&tcp_loader_process); tcp_markconn(uip_conn, &s); if(elfloader_autostart_processes != NULL) { PRINTF("Stopping old programs.\n"); autostart_exit(elfloader_autostart_processes); elfloader_autostart_processes = NULL; } } else { PRINTF(("codeprop: uip_connected() and data != NULL\n")); uip_abort(); } } recv_tcpthread(&s.tcpthread_pt); /* Run thread */ if(uip_closed() || uip_aborted() || uip_timedout()) { PRINTF(("codeprop: connection down\n")); tcp_markconn(uip_conn, NULL); } } } PROCESS_END(); }
static void fs20_net_main(void) // Network-routine called by networkstack { if (uip_aborted() || uip_timedout()) // Connection aborted or timedout { // if connectionstate is new, we have to resend the packet, otherwise just ignore the event if (uip_conn->appstate.fs20.state == FS20_CONNSTATE_NEW) { fs20_sendstate = 2; // Ignore aborted, if already closed uip_conn->appstate.fs20.state = FS20_CONNSTATE_OLD; FS20S_DEBUG ("connection aborted\n"); return; } } if (uip_closed()) // Closed connection does not expect any respond from us, resend if connnectionstate is new { if (uip_conn->appstate.fs20.state == FS20_CONNSTATE_NEW) { fs20_sendstate = 2; // Ignore aborted, if already closed uip_conn->appstate.fs20.state = FS20_CONNSTATE_OLD; FS20S_DEBUG ("new connection closed\n"); } else { FS20S_DEBUG ("connection closed\n"); } return; } if (uip_connected() || uip_rexmit()) { // (re-)transmit packet FS20S_DEBUG ("new connection or rexmit, sending message\n"); char *p = uip_appdata; // pointer set to uip_appdata, used to store string p += sprintf_P(p, PSTR("fs20 ")); if (fs20_global.fs20.queue[fs20_qpos].ext) { p += sprintf_P(p, PSTR("%02x%02x%02x%02x%02x"), fs20_global.fs20.queue[fs20_qpos].data.edg.hc1, fs20_global.fs20.queue[fs20_qpos].data.edg.hc2, fs20_global.fs20.queue[fs20_qpos].data.edg.addr, fs20_global.fs20.queue[fs20_qpos].data.edg.cmd, fs20_global.fs20.queue[fs20_qpos].data.edg.cmd2); } else { p += sprintf_P(p, PSTR("%02x%02x%02x%02x"), fs20_global.fs20.queue[fs20_qpos].data.dg.hc1, fs20_global.fs20.queue[fs20_qpos].data.dg.hc2, fs20_global.fs20.queue[fs20_qpos].data.dg.addr, fs20_global.fs20.queue[fs20_qpos].data.dg.cmd); } fs20_global.fs20.queue[fs20_qpos].send = 0; uip_udp_send(p - (char *)uip_appdata); FS20S_DEBUG ("send %d bytes\n", p - (char *)uip_appdata); FS20S_DEBUG ("send %s\n", uip_appdata); } if (uip_acked()) // Send packet acked, { if (uip_conn->appstate.fs20.state == FS20_CONNSTATE_NEW) // If packet is still new { fs20_sendstate = 0; // Mark event as sent, go ahead in buffer uip_conn->appstate.fs20.state = FS20_CONNSTATE_OLD; // mark this packet as old, do not resend it uip_close(); // initiate closing of the connection FS20S_DEBUG ("packet sent, closing\n"); return; } else { uip_abort(); // abort connection if old connection received an ack... this should not happen } } }
/*-----------------------------------------------------------------------------------*/ void webclient_appcall(void *state) { char *dataptr; if(uip_connected()) { s.timer = 0; s.state = WEBCLIENT_STATE_STATUSLINE; senddata(); webclient_connected(); tcp_markconn(uip_conn, &s); return; } if(uip_timedout()) { webclient_timedout(); } if(uip_aborted()) { webclient_aborted(); } if(state == NULL) { uip_abort(); return; } if(s.state == WEBCLIENT_STATE_CLOSE) { webclient_closed(); uip_abort(); return; } /* The acked() and newdata() functions may alter the uip_appdata ptr, so we need to store it in the "dataptr" variable so that we can restore it before the senddata() function is called. */ dataptr = uip_appdata; if(uip_acked()) { s.timer = 0; acked(); } if(uip_newdata()) { s.timer = 0; newdata(); } uip_appdata = dataptr; if(uip_rexmit() || uip_newdata() || uip_acked()) { senddata(); } else if(uip_poll()) { ++s.timer; if(s.timer == WEBCLIENT_TIMEOUT) { webclient_timedout(); uip_abort(); return; } /* senddata();*/ } if(uip_closed()) { tcp_markconn(uip_conn, NULL); if(s.httpflag != HTTPFLAG_MOVED) { /* Send NULL data to signal EOF. */ webclient_datahandler(NULL, 0); } else { /* conn = uip_connect(uip_conn->ripaddr, s.port); if(conn != NULL) { dispatcher_markconn(conn, NULL); init_connection(); }*/ #if UIP_UDP if(resolv_lookup(s.host) == NULL) { resolv_query(s.host); } #endif /* UIP_UDP */ webclient_get(s.host, s.port, s.file); } } }