Esempio n. 1
0
/* This is called by contiki/ip/tcpip.c:tcpip_uipcall() when packet
 * is processed.
 */
PROCESS_THREAD(tcp, ev, data, buf, user_data)
{
	PROCESS_BEGIN();

	while(1) {
		PROCESS_YIELD_UNTIL(ev == tcpip_event);

		if (POINTER_TO_INT(data) == TCP_WRITE_EVENT) {
			/* We want to send data to peer. */
			struct net_context *context = user_data;

			if (!context) {
				continue;
			}

			do {
				context = user_data;
				if (!context || !buf) {
					break;
				}

				if (!context->ps.net_buf ||
				    context->ps.net_buf != buf) {
					NET_DBG("psock init %p buf %p\n",
						&context->ps, buf);
					PSOCK_INIT(&context->ps, buf);
				}

				handle_tcp_connection(&context->ps,
						      POINTER_TO_INT(data),
						      buf);

				PROCESS_WAIT_EVENT_UNTIL(ev == tcpip_event);

				if (POINTER_TO_INT(data) != TCP_WRITE_EVENT) {
					goto read_data;
				}
			} while(!(uip_closed(buf)  ||
				  uip_aborted(buf) ||
				  uip_timedout(buf)));

			context = user_data;

			if (context &&
			    context->tcp_type == NET_TCP_TYPE_CLIENT) {
				NET_DBG("\nConnection closed.\n");
				ip_buf_sent_status(buf) = -ECONNRESET;
			}

			continue;
		}

	read_data:
		/* We are receiving data from peer. */
		if (buf && uip_newdata(buf)) {
			struct net_buf *clone;

			if (!uip_len(buf)) {
				continue;
			}

			/* Note that uIP stack will reuse the buffer when
			 * sending ACK to peer host. The sending will happen
			 * right after this function returns. Because of this
			 * we cannot use the same buffer to pass data to
			 * application.
			 */
			clone = net_buf_clone(buf);
			if (!clone) {
				NET_ERR("No enough RX buffers, "
					"packet %p discarded\n", buf);
				continue;
			}

			ip_buf_appdata(clone) = uip_buf(clone) +
				(ip_buf_appdata(buf) - (void *)uip_buf(buf));
			ip_buf_appdatalen(clone) = uip_len(buf);
			ip_buf_len(clone) = ip_buf_len(buf);
			ip_buf_context(clone) = user_data;
			uip_set_conn(clone) = uip_conn(buf);
			uip_flags(clone) = uip_flags(buf);
			uip_flags(clone) |= UIP_CONNECTED;

			NET_DBG("packet received context %p buf %p len %d "
				"appdata %p appdatalen %d\n",
				ip_buf_context(clone),
				clone,
				ip_buf_len(clone),
				ip_buf_appdata(clone),
				ip_buf_appdatalen(clone));

			nano_fifo_put(net_context_get_queue(user_data), clone);

			/* We let the application to read the data now */
			fiber_yield();
		}
	}

	PROCESS_END();
}
Esempio n. 2
0
/* Run Server
 *  Function tat will create a new socket, accept and handle connections from clients
 */
void run_server ( settings_t **settings, char* ( *callback ) ( char* ) ) {
    fd_set master;
    fd_set readSet;
    
    
    int listener;
    int new_fd;
    int max_fd;    
  
    int i;
    
    /* Create our socket for handling connections */
    listener = create_tcp_socket ( LISTEN_PORT );
    
    /* Zero out the master fd_set */
    FD_ZERO ( &master );
    
    /* Add the server socket to the set of sockets */
    FD_SET ( listener, &master );
    
    /* The highest file descriptor (fd) */
    max_fd = listener;
    
    /* Infinite loop */
    for ( ;; ) {
        
        /* Copy the master set into a temporary fd */
        readSet = master;
        
        /* Handle multiple connections via Select */
        if ( select ( max_fd + 1, &readSet, NULL, NULL, NULL ) == -1 ) {
            DIE ( "select() failed" );
            
        }
        
        /* Spin through all of the items in readSet and check for connections or requests */
        for ( i = 0; i <= max_fd; i++ ) {
            
            /* We've got a new one! */
            if (FD_ISSET ( i, &readSet ) ) {
                if ( i == listener ) {
                
                    /* Accept a new client */
                    new_fd = accept_tcp_connection ( listener );
                    
                    
                    /* Add it to the list of sockets */
                    FD_SET ( new_fd, &master );
                
                    /* Specify the new max, if need be */
                    if ( new_fd > max_fd ) {
                        max_fd = new_fd;
                    }
                    
                } else {
                    
                    /* Process information coming from a given socket, and close if necessary */
                    if ( handle_tcp_connection ( i, callback ) == 0 ) {
                        close ( i );
                        FD_CLR ( i, &master );
                    }
                    
                }
            }
        }
    }
    
    /* shut down */
    close ( listener );

    
}