コード例 #1
0
static void ISocketFree(T_Network_lwIP_Workspace *p, T_uezNetworkSocket aSocket)
{
    T_lwIPSocket *p_socket = p->iSockets + aSocket;

    p_socket->iState = SOCKET_STATE_FREE;
    p_socket->iType = UEZ_NETWORK_SOCKET_TYPE_TCP;
    p_socket->iFlags = 0;
    if (p_socket->iReceiveNetBuf) {
        netbuf_delete(p_socket->iReceiveNetBuf);
        p_socket->iReceiveNetBuf = 0;
    }
    p_socket->iReceiveData = 0;
    p_socket->iReceiveLength = 0;
    p_socket->iReceiveRemaining = 0;
    p_socket->iPort = 0;
    p_socket->iNetconn = 0;
    p_socket->iSourcePort = 0;
}
コード例 #2
0
ファイル: lwip_stack.c プロジェクト: infinnovation/mbed-os
static nsapi_size_or_error_t mbed_lwip_socket_recvfrom(nsapi_stack_t *stack, nsapi_socket_t handle, nsapi_addr_t *addr, uint16_t *port, void *data, nsapi_size_t size)
{
    struct lwip_socket *s = (struct lwip_socket *)handle;
    struct netbuf *buf;

    err_t err = netconn_recv(s->conn, &buf);
    if (err != ERR_OK) {
        return mbed_lwip_err_remap(err);
    }

    convert_lwip_addr_to_mbed(addr, netbuf_fromaddr(buf));
    *port = netbuf_fromport(buf);

    u16_t recv = netbuf_copy(buf, data, (u16_t)size);
    netbuf_delete(buf);

    return recv;
}
コード例 #3
0
ファイル: data_udp.c プロジェクト: wa2tqi/stm32
/*! \brief event handler for mpu9150 udp data
 *  send one packet of mpu9150 data on event.
 */
static void data_udp_send_mpu9150_data(eventid_t id) {
	(void) id;
	uint8_t*                  data;
	BaseSequentialStream *chp = getActiveUsbSerialStream();

	mpu9150_mac_info.buf     =  netbuf_new();
	chprintf(chp, "ACCL:  x: %d\ty: %d\tz: %d\r\n", mpu9150_current_read.accel_xyz.x, mpu9150_current_read.accel_xyz.y, mpu9150_current_read.accel_xyz.z);

	data    =  netbuf_alloc(mpu9150_mac_info.buf, sizeof(MPU9150_read_data));
	if(data != NULL) {
		memcpy (data, (void*) &mpu9150_current_read, sizeof(MPU9150_read_data));
		chprintf(chp, "size: %d\r\n", sizeof(MPU9150_read_data));

		palSetPad(TIMEOUTPUT_PORT, TIMEOUTPUT_PIN);
		netconn_send(mpu9150_mac_info.conn, mpu9150_mac_info.buf);
		palClearPad(TIMEOUTPUT_PORT, TIMEOUTPUT_PIN);
		netbuf_delete(mpu9150_mac_info.buf);
	}
}
コード例 #4
0
ファイル: uctsk_LWIP.c プロジェクト: saeedhadi/Metering
/*******************************************************************************
* Function Name  : vHandler_HTTP
* Description    : HTTP处理
* Input          : - pstConn: 指向struct netconn结构的指针
* Output         : None
* Return         : None
* Attention		 : None
*******************************************************************************/
static void vHandler_HTTP(struct netconn  *pstConn)
{
	struct netbuf 		*__pstNetbuf;
	INT8S			*__pbData;
	u16_t			__s32Len;

 	__pstNetbuf = netconn_recv(pstConn);
	if(__pstNetbuf != NULL)
	{
		netbuf_data (__pstNetbuf, (void *)&__pbData, &__s32Len );

		if( strstr( (void *)__pbData, "GET" ) != NULL )
		{
			__Handler_HTTPGet(pstConn); 
	    }
	}
	netbuf_delete(__pstNetbuf);	
	netconn_close(pstConn);
}
コード例 #5
0
ファイル: lwip_stack.c プロジェクト: andreaslarssonublox/mbed
static int lwip_socket_recvfrom(nsapi_stack_t *stack, nsapi_socket_t handle, nsapi_addr_t *addr, uint16_t *port, void *data, unsigned size)
{
    struct lwip_socket *s = (struct lwip_socket *)handle;

    struct netbuf *buf;
    err_t err = netconn_recv(s->conn, &buf);
    if (err != ERR_OK) {
        return lwip_err_remap(err);
    }

    addr->version = NSAPI_IPv4;
    memcpy(addr->bytes, netbuf_fromaddr(buf), sizeof addr->bytes);
    *port = netbuf_fromport(buf);

    u16_t recv = netbuf_copy(buf, data, (u16_t)size);
    netbuf_delete(buf);

    return recv;
}
コード例 #6
0
/** Serve one HTTP connection accepted in the http thread */
static void
http_server_netconn_serve(struct netconn *conn)
{
  struct netbuf *inbuf;
  char *buf;
  u16_t buflen;
  err_t err;
  
  /* Read the data from the port, blocking if nothing yet there. 
   We assume the request (the part we care about) is in one netbuf */
  err = netconn_recv(conn, &inbuf);
  
  if (err == ERR_OK) {
    netbuf_data(inbuf, (void**)&buf, &buflen);
    
    /* Is this an HTTP GET command? (only check the first 5 chars, since
    there are other formats for GET, and we're keeping it very simple )*/
    if (buflen>=5 &&
        buf[0]=='G' &&
        buf[1]=='E' &&
        buf[2]=='T' &&
        buf[3]==' ' &&
        buf[4]=='/' ) {
      
      /* Send the HTML header 
             * subtract 1 from the size, since we dont send the \0 in the string
             * NETCONN_NOCOPY: our data is const static, so no need to copy it
       */
      printf(" Recieved a proper HTTP request sending out the http headers\n");
      int ret = netconn_write(conn, http_html_hdr, sizeof(http_html_hdr)-1, NETCONN_NOCOPY);
      
      /* Send our HTML page */
      netconn_write(conn, http_index_html, sizeof(http_index_html)-1, NETCONN_NOCOPY);
    }
  }
  /* Close the connection (server closes in HTTP) */
  netconn_close(conn);
  
  /* Delete the buffer (netconn_recv gives us ownership,
   so we have to make sure to deallocate the buffer) */
  netbuf_delete(inbuf);
}
コード例 #7
0
ファイル: data_udp.c プロジェクト: wa2tqi/stm32
static void data_udp_rx_serve(struct netconn *conn) {
#if DEBUG_SENSOR_UDP
	static uint8_t       count  = 0;
	BaseSequentialStream *chp = getActiveUsbSerialStream();
#endif

	struct netbuf        *inbuf;

	char                 *buf;

	uint16_t             buflen = 0;

	err_t                err;

	/*
	 * Read the data from the port, blocking if nothing yet there.
	 * We assume the request (the part we care about) is in one netbuf
	 */
	err = netconn_recv(conn, &inbuf);
	if (err == ERR_OK) {
		netbuf_data(inbuf, (void **)&buf, &buflen);
		//palClearPad(TIMEINPUT_PORT, TIMEINPUT_PIN);     // negative pulse for input.
#if DEBUG_SENSOR_UDP
		chprintf(chp, "\r\nsensor rx (from FC): %d ", count++);
#endif
		//palSetPad(TIMEINPUT_PORT, TIMEINPUT_PIN);
#if DEBUG_SENSOR_UDP
		uint16_t             i      = 0;
		for(i=0; i<buflen; ++i) {
			chprintf(chp, "%c", buf[i]);
		}
		chprintf(chp, "\r\n");
#endif
		data_udp_process_rx(buf, buflen);
	}
	netconn_close(conn);

	/* Delete the buffer (netconn_recv gives us ownership,
	 * so we have to make sure to deallocate the buffer)
	 */
	netbuf_delete(inbuf);
}
コード例 #8
0
ファイル: net_test.c プロジェクト: CollinsLiu/rt-thread-pc
void tcpecho_entry(void *parameter)
{
	struct netconn *conn, *newconn;
	err_t err;

	/* Create a new connection identifier. */
	conn = netconn_new(NETCONN_TCP);

	/* Bind connection to well known port number 7. */
	netconn_bind(conn, NULL, TCP_ECHO_PORT);

	/* Tell connection to go into listening mode. */
	netconn_listen(conn);

	while(1)
	{
		/* Grab new connection. */
		newconn = netconn_accept(conn);
		/* Process the new connection. */
		if(newconn != NULL)
		{
			struct netbuf *buf;
			void *data;
			u16_t len;

			while((buf = netconn_recv(newconn)) != NULL)
			{
				do
				{
					netbuf_data(buf, &data, &len);
					err = netconn_write(newconn, data, len, NETCONN_COPY);
					if(err != ERR_OK){}
				}
				while(netbuf_next(buf) >= 0);
				netbuf_delete(buf);
			}
			/* Close connection and discard connection identifier. */
			netconn_delete(newconn);
		}
	}
}
コード例 #9
0
ファイル: udpecho.c プロジェクト: 10code/lwip
void 
udpecho_thread(void *arg)
{
  struct netconn *conn;
  struct netbuf *buf;
  struct ip_addr *addr;
  unsigned short port;
  
  conn = netconn_new(NETCONN_UDP);
  netconn_bind(conn, NULL, 7);

  while(1) {
    buf = netconn_recv(conn);
    addr = netbuf_fromaddr(buf);
    port = netbuf_fromport(buf);
    netconn_connect(conn, addr, port);
    netconn_send(conn, buf);
    netbuf_copy(buf, buffer, sizeof(buffer));
    netbuf_delete(buf);
  }
}
コード例 #10
0
ファイル: lwip-net.c プロジェクト: naredula-jana/Jiny-Kernel
int lwip_sock_read_from(void *conn, unsigned char *buff, unsigned long len,struct sockaddr *sockaddr, int addr_len) {
	struct netbuf *new_buf=0;
	unsigned char *data;
	int data_len=0;
	int ret=0;

	SYSCALL_DEBUG(" SOCK recvfrom :%x len:%d \n",buff,len);

	mutexLock(g_netBH_lock);
	ret=netconn_recv(conn,  &new_buf);
	mutexUnLock(g_netBH_lock);
if (ret == ERR_TIMEOUT){
	if (g_current_task->killed == 1){
		return 0;
	}
}

	if (ret!=ERR_OK){
		SYSCALL_DEBUG(" Fail to recvfrom data: %x newret:%x(%d) \n",ret,-ret,-ret);
		return 0;
	}
	SYSCALL_DEBUG(" SUCESS to recv data:%d \n",ret);
	netbuf_data(new_buf,&data,&data_len);
	if (data_len >  0){
		if (sockaddr != 0){
			sockaddr->addr = new_buf->addr.addr;
			sockaddr->sin_port = new_buf->port;
		}
		ut_memcpy(buff,data,ut_min(data_len,len));
		ret = ut_min(data_len,len);
	}else{
		ret =0;
	}

	mutexLock(g_netBH_lock);
	netbuf_delete(new_buf);
	mutexUnLock(g_netBH_lock);

	return ret;
}
コード例 #11
0
ファイル: data_udp.c プロジェクト: wa2tqi/stm32
static void data_udp_rx_serve(struct netconn *conn) {
	BaseSequentialStream *chp   =  (BaseSequentialStream *)&SD1;

	static uint8_t       count  = 0;

	struct netbuf        *inbuf;

	char                 *buf;

	uint16_t             buflen = 0;
	uint16_t             i      = 0;

	ip_addr_t            my_ip;

	uint16_t             my_port;
	err_t                err;

	/*
	 * Read the data from the port, blocking if nothing yet there.
	 * We assume the request (the part we care about) is in one netbuf
	 */
	err = netconn_recv(conn, &inbuf);
	netconn_getaddr(conn, &my_ip, &my_port,  local_ip);
	print_ip(my_ip, my_port);

	if (err == ERR_OK) {
		netbuf_data(inbuf, (void **)&buf, &buflen);
		chprintf(chp, "\r\nsensor rx:%d:->", count++);
		for(i=0; i<buflen; ++i) {
			chprintf(chp, "%c", buf[i]);
		}
		chprintf(chp, "\r\n");
	}
	netconn_close(conn);

	/* Delete the buffer (netconn_recv gives us ownership,
	 * so we have to make sure to deallocate the buffer)
	 */
	netbuf_delete(inbuf);
}
コード例 #12
0
ファイル: data_udp.c プロジェクト: wa2tqi/stm32
/*! \brief event handler for mpu9150 udp data
 *  send one packet of mpu9150 data on event.
 */
static void data_udp_send_mpl3115a2_data(eventid_t id) {
    (void) id;
    uint8_t*                  data;
    MPL_packet                packet;
    const char                myid[(sizeof("MPL3")-1)] = "MPL3";

    memset (&packet.timestamp, 0, sizeof(packet.timestamp));

    strncpy(packet.ID, myid, sizeof(myid));

    memcpy(&packet.data, (void*) &mpl3115a2_current_read, sizeof(MPL3115A2_read_data) );

    packet.data_length         =  (uint16_t) sizeof(MPL3115A2_read_data);
    mpl3115a2_mac_info.buf     =  netbuf_new();

    data    =  netbuf_alloc(mpl3115a2_mac_info.buf, sizeof(packet));
    if(data != NULL) {
        memcpy (data, (void*) &packet, sizeof(packet));
        netconn_send(mpl3115a2_mac_info.conn, mpl3115a2_mac_info.buf);
        netbuf_delete(mpl3115a2_mac_info.buf);
    }
}
コード例 #13
0
ファイル: lwip_stack.c プロジェクト: andreaslarssonublox/mbed
static int lwip_socket_sendto(nsapi_stack_t *stack, nsapi_socket_t handle, nsapi_addr_t addr, uint16_t port, const void *data, unsigned size)
{
    struct lwip_socket *s = (struct lwip_socket *)handle;
    if (addr.version != NSAPI_IPv4) {
        return NSAPI_ERROR_PARAMETER;
    }

    struct netbuf *buf = netbuf_new();
    err_t err = netbuf_ref(buf, data, (u16_t)size);
    if (err != ERR_OK) {
        netbuf_free(buf);
        return lwip_err_remap(err);;
    }

    err = netconn_sendto(s->conn, buf, (ip_addr_t *)addr.bytes, port);
    netbuf_delete(buf);
    if (err != ERR_OK) {
        return lwip_err_remap(err);
    }

    return size;
}
コード例 #14
0
ファイル: LWIPStack.cpp プロジェクト: donatieng/mbed
nsapi_size_or_error_t LWIP::socket_recvfrom(nsapi_socket_t handle, SocketAddress *address, void *data, nsapi_size_t size)
{
    struct mbed_lwip_socket *s = (struct mbed_lwip_socket *)handle;
    struct netbuf *buf;

    err_t err = netconn_recv(s->conn, &buf);
    if (err != ERR_OK) {
        return err_remap(err);
    }

    if (address) {
        nsapi_addr_t addr;
        convert_lwip_addr_to_mbed(&addr, netbuf_fromaddr(buf));
        address->set_addr(addr);
        address->set_port(netbuf_fromport(buf));
    }

    u16_t recv = netbuf_copy(buf, data, (u16_t)size);
    netbuf_delete(buf);

    return recv;
}
コード例 #15
0
ファイル: web.c プロジェクト: nhzandi/EchoServer-ChibiOS
/**
 * UDP echo server thread.
 */
msg_t udp_echo_server(void *p)
{
  err_t err, recv_err;
  
  LWIP_UNUSED_ARG(p);

  conn = netconn_new(NETCONN_UDP);
  if (conn!= NULL)
  {
    err = netconn_bind(conn, IP_ADDR_ANY, UDP_THREAD_PORT);
    if (err == ERR_OK)
    {
      while (1) 
      {
        recv_err = netconn_recv(conn, &buf);
      
        if (recv_err == ERR_OK) 
        {
          addr = netbuf_fromaddr(buf);
          port = netbuf_fromport(buf);
          netconn_connect(conn, addr, port);
          buf->addr.addr = 0;
          netconn_send(conn,buf);
          netbuf_delete(buf);
        }
      }
    }
    else
    {
      netconn_delete(conn);
      // printf("can not bind netconn");
    }
  }
  else
  {
    // printf("can create new UDP netconn");
  }
  return RDY_OK;
}
コード例 #16
0
/*-----------------------------------------------------------------------------------*/
static void udpecho_thread(void *arg)
{
  err_t err, recv_err;
  
  LWIP_UNUSED_ARG(arg);

  conn = netconn_new(NETCONN_UDP);
  if (conn!= NULL)
  {
    err = netconn_bind(conn, IP_ADDR_ANY, 7);
    if (err == ERR_OK)
    {
      while (1) 
      {
        recv_err = netconn_recv(conn, &buf);
      
        if (recv_err == ERR_OK) 
        {
          addr = netbuf_fromaddr(buf);
          port = netbuf_fromport(buf);
          netconn_connect(conn, addr, port);
          buf->addr.addr = 0;
          netconn_send(conn,buf);
          netbuf_delete(buf);
        }
      }
    }
    else
    {
      netconn_delete(conn);
      printf("can not bind netconn");
    }
  }
  else
  {
    printf("can create new UDP netconn");
  }
}
コード例 #17
0
static void udpecho_thread(void *arg)
{
    static struct netconn *conn;
    static struct netbuf *buf;
    char buffer[100];
    err_t err;

    LWIP_UNUSED_ARG(arg);
    netif_set_up(&fsl_netif0);
    conn = netconn_new(NETCONN_UDP);
    LWIP_ASSERT("con != NULL", conn != NULL);
    netconn_bind(conn, NULL, 7);
    while (1)
    {
        err = netconn_recv(conn, &buf);
        if (err == ERR_OK)
        {
            if (netbuf_copy(buf, buffer, buf->p->tot_len) != buf->p->tot_len)
            {
                LWIP_DEBUGF(UDPECHO_DBG, ("netbuf_copy failed\r\n"));
            }
            else
            {
                buffer[buf->p->tot_len] = '\0';
                err = netconn_send(conn, buf);
                if (err != ERR_OK)
                {
                    LWIP_DEBUGF(UDPECHO_DBG, ("netconn_send failed: %d\r\n", (int)err));
                }
                else
                {
                    LWIP_DEBUGF(UDPECHO_DBG, ("got %s\r\n", buffer));
                }
            }
            netbuf_delete(buf);
        }
    }
}
コード例 #18
0
ファイル: lwip_stack.c プロジェクト: andreaslarssonublox/mbed
static int lwip_socket_recv(nsapi_stack_t *stack, nsapi_socket_t handle, void *data, unsigned size)
{
    struct lwip_socket *s = (struct lwip_socket *)handle;

    if (!s->buf) {
        err_t err = netconn_recv(s->conn, &s->buf);
        s->offset = 0;

        if (err != ERR_OK) {
            return (err == ERR_CLSD) ? 0 : lwip_err_remap(err);
        }
    }

    u16_t recv = netbuf_copy_partial(s->buf, data, (u16_t)size, s->offset);
    s->offset += recv;

    if (s->offset >= netbuf_len(s->buf)) {
        netbuf_delete(s->buf);
        s->buf = 0;
    }

    return recv;
}
コード例 #19
0
ファイル: LWIPStack.cpp プロジェクト: donatieng/mbed
nsapi_size_or_error_t LWIP::socket_recv(nsapi_socket_t handle, void *data, nsapi_size_t size)
{
    struct mbed_lwip_socket *s = (struct mbed_lwip_socket *)handle;

    if (!s->buf) {
        err_t err = netconn_recv(s->conn, &s->buf);
        s->offset = 0;

        if (err != ERR_OK) {
            return err_remap(err);
        }
    }

    u16_t recv = netbuf_copy_partial(s->buf, data, (u16_t)size, s->offset);
    s->offset += recv;

    if (s->offset >= netbuf_len(s->buf)) {
        netbuf_delete(s->buf);
        s->buf = 0;
    }

    return recv;
}
コード例 #20
0
ファイル: ZWaveTCP.c プロジェクト: garlicnation/zwave
/*! \brief parse the incoming request
 *         parse the HTML request and send file
 *
 *  \param pxNetCon   Input. The netconn to use to send and receive data.
 *
 */
static void prvweb_HandleZwaveSession( struct netconn *pxNetCon )
{
	portCHAR *pcRxString;
	unsigned portSHORT usLength;
	char to_send[100];
	size_t to_send_idx = 0;
	unsigned short i;


	while((pxNetCon->err & ERR_CLSD) == 0){
		pxRxBuffer = netconn_recv(pxNetCon);
		if (pxRxBuffer != NULL){
			netbuf_data(pxRxBuffer, (void*)&pcRxString, &usLength);
			vParTestToggleLED(5);
			for(i = 0; i < usLength; i++){
				xQueueSend(zw_tcp_recv_queue, pcRxString+i, 100);
			}
			netbuf_delete(pxRxBuffer);
		}
		if (usart_recv_queue && uxQueueMessagesWaiting(usart_recv_queue)){
			vParTestToggleLED(4);
			while(uxQueueMessagesWaiting(usart_recv_queue)>0 && to_send_idx < 100){
				vParTestToggleLED(3);
				xQueueReceive(usart_recv_queue, (to_send+to_send_idx), 100);
				to_send_idx++;
			}
			if (to_send_idx>0){
				netconn_write(pxNetCon, to_send, to_send_idx, NETCONN_COPY);
				to_send_idx = 0;
			}
		}
		vTaskDelay(100/portTICK_RATE_MS);
	}

	netconn_close( pxNetCon );
	netconn_delete( pxNetCon );
}
コード例 #21
0
ファイル: udpecho.c プロジェクト: AleksKolkov/lrndis
/*-----------------------------------------------------------------------------------*/
static void
udpecho_thread(void *arg)
{
  static struct netconn *conn;
  static struct netbuf *buf;
  static ip_addr_t *addr;
  static unsigned short port;
  char buffer[4096];
  err_t err;
  LWIP_UNUSED_ARG(arg);

  conn = netconn_new(NETCONN_UDP);
  LWIP_ASSERT("con != NULL", conn != NULL);
  netconn_bind(conn, NULL, 7);

  while (1) {
    err = netconn_recv(conn, &buf);
    if (err == ERR_OK) {
      addr = netbuf_fromaddr(buf);
      port = netbuf_fromport(buf);
      /*  no need netconn_connect here, since the netbuf contains the address */
      if(netbuf_copy(buf, buffer, buf->p->tot_len) != buf->p->tot_len) {
        LWIP_DEBUGF(LWIP_DBG_ON, ("netbuf_copy failed\n"));
      } else {
        buffer[buf->p->tot_len] = '\0';
        err = netconn_send(conn, buf);
        if(err != ERR_OK) {
          LWIP_DEBUGF(LWIP_DBG_ON, ("netconn_send failed: %d\n", (int)err));
        } else {
          LWIP_DEBUGF(LWIP_DBG_ON, ("got %s\n", buffer));
        }
      }
      netbuf_delete(buf);
    }
  }
}
コード例 #22
0
ファイル: sip_api.c プロジェクト: lzjsqn/19
int close(int s)
{
	struct lwip_socket *sock;

	sock = get_socket(s);
	if (!sock) 
	{
		return -1;
	}

	netconn_delete(sock->conn);

	sys_sem_wait(socksem);
	if (sock->lastdata) 
	{
		netbuf_delete(sock->lastdata);
	}
	sock->lastdata   = NULL;
	sock->lastoffset = 0;
	sock->conn       = NULL;
	sys_sem_signal(socksem);

	return 0;
}
コード例 #23
0
ファイル: data_udp.c プロジェクト: wa2tqi/stm32
/*! \brief event handler for adis16405 udp data
 *  send one packet of adis16405 data on event.
 */
static void data_udp_send_adis16405_data(eventid_t id) {
	(void) id;
	ADIS_packet               packet;
    const char                myid[(sizeof("ADIS")-1)] = "ADIS";

	uint8_t*                  data;

	memset (&packet.timestamp, 0, sizeof(packet.timestamp));

	strncpy(packet.ID, myid, sizeof(myid));

	memcpy(&packet.data, (void*) &adis16405_burst_data, sizeof(ADIS16405_burst_data) );

	packet.data_length       =  (uint16_t) sizeof(ADIS16405_burst_data);

	adis16405_mac_info.buf     =  netbuf_new();

	data    =  netbuf_alloc(adis16405_mac_info.buf, sizeof(ADIS_packet));
	if(data != NULL) {
		memcpy (data, (void*) &packet, sizeof(ADIS_packet));
		netconn_send(adis16405_mac_info.conn, adis16405_mac_info.buf);
		netbuf_delete(adis16405_mac_info.buf);
	}
}
コード例 #24
0
ファイル: udpecho.c プロジェクト: NKSG/INTER_MANET_NS3
/*-----------------------------------------------------------------------------------*/
void 
udpecho_thread(void *arg)
{
  static struct netconn *conn;
  static struct netbuf *buf;
  static struct ip_addr *addr;
  static unsigned short port;
  char buffer[4096];
  
  conn = netconn_new(NETCONN_UDP);
  netconn_bind(conn, NULL, 7);

  while (1) {
    buf = netconn_recv(conn);
    addr = netbuf_fromaddr(buf);
    port = netbuf_fromport(buf);
    netconn_connect(conn, addr, port);
    netbuf_copy(buf, buffer, buf->p->tot_len);
    buffer[buf->p->tot_len] = '\0';
    netconn_send(conn, buf);
    printf("got %s\n", buffer);
    netbuf_delete(buf);
  }
}
コード例 #25
0
static nsapi_size_or_error_t mbed_lwip_socket_sendto(nsapi_stack_t *stack, nsapi_socket_t handle, nsapi_addr_t addr, uint16_t port, const void *data, nsapi_size_t size)
{
    struct lwip_socket *s = (struct lwip_socket *)handle;
    ip_addr_t ip_addr;

    if (!convert_mbed_addr_to_lwip(&ip_addr, &addr)) {
        return NSAPI_ERROR_PARAMETER;
    }

    struct netbuf *buf = netbuf_new();
    err_t err = netbuf_ref(buf, data, (u16_t)size);
    if (err != ERR_OK) {
        netbuf_free(buf);
        return mbed_lwip_err_remap(err);
    }

    err = netconn_sendto(s->conn, buf, &ip_addr, port);
    netbuf_delete(buf);
    if (err != ERR_OK) {
        return mbed_lwip_err_remap(err);
    }

    return size;
}
コード例 #26
0
ファイル: api_msg.c プロジェクト: comrid1987/jb3500
/**
 * Receive callback function for UDP netconns.
 * Posts the packet to conn->recvmbox or deletes it on memory error.
 *
 * @see udp.h (struct udp_pcb.recv) for parameters
 */
static void
recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p,
         ip_addr_t *addr, u16_t port)
{
    struct netbuf *buf;
    struct netconn *conn;
    u16_t len;
#if LWIP_SO_RCVBUF
    int recv_avail;
#endif /* LWIP_SO_RCVBUF */

    LWIP_UNUSED_ARG(pcb); /* only used for asserts... */
    LWIP_ASSERT("recv_udp must have a pcb argument", pcb != NULL);
    LWIP_ASSERT("recv_udp must have an argument", arg != NULL);
    conn = (struct netconn *)arg;
    LWIP_ASSERT("recv_udp: recv for wrong pcb!", conn->pcb.udp == pcb);

#if LWIP_SO_RCVBUF
    SYS_ARCH_GET(conn->recv_avail, recv_avail);
    if ((conn == NULL) || !sys_mbox_valid(&conn->recvmbox) ||
            ((recv_avail + (int)(p->tot_len)) > conn->recv_bufsize)) {
#else  /* LWIP_SO_RCVBUF */
    if ((conn == NULL) || !sys_mbox_valid(&conn->recvmbox)) {
#endif /* LWIP_SO_RCVBUF */
        pbuf_free(p);
        return;
    }

    buf = (struct netbuf *)memp_malloc(MEMP_NETBUF);
    if (buf == NULL) {
        pbuf_free(p);
        return;
    } else {
        buf->p = p;
        buf->ptr = p;
        ip_addr_set(&buf->addr, addr);
        buf->port = port;
#if LWIP_NETBUF_RECVINFO
        {
            const struct ip_hdr* iphdr = ip_current_header();
            /* get the UDP header - always in the first pbuf, ensured by udp_input */
            const struct udp_hdr* udphdr = (void*)(((char*)iphdr) + IPH_LEN(iphdr));
#if LWIP_CHECKSUM_ON_COPY
            buf->flags = NETBUF_FLAG_DESTADDR;
#endif /* LWIP_CHECKSUM_ON_COPY */
            ip_addr_set(&buf->toaddr, ip_current_dest_addr());
            buf->toport_chksum = udphdr->dest;
        }
#endif /* LWIP_NETBUF_RECVINFO */
    }

    len = p->tot_len;
    if (sys_mbox_trypost(&conn->recvmbox, buf) != ERR_OK) {
        netbuf_delete(buf);
        return;
    } else {
#if LWIP_SO_RCVBUF
        SYS_ARCH_INC(conn->recv_avail, len);
#endif /* LWIP_SO_RCVBUF */
        /* Register event with callback */
        API_EVENT(conn, NETCONN_EVT_RCVPLUS, len);
    }
}
#endif /* LWIP_UDP */

#if LWIP_TCP
/**
 * Receive callback function for TCP netconns.
 * Posts the packet to conn->recvmbox, but doesn't delete it on errors.
 *
 * @see tcp.h (struct tcp_pcb.recv) for parameters and return value
 */
static err_t
recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
    struct netconn *conn;
    u16_t len;

    LWIP_UNUSED_ARG(pcb);
    LWIP_ASSERT("recv_tcp must have a pcb argument", pcb != NULL);
    LWIP_ASSERT("recv_tcp must have an argument", arg != NULL);
    conn = (struct netconn *)arg;
    LWIP_ASSERT("recv_tcp: recv for wrong pcb!", conn->pcb.tcp == pcb);

    if (conn == NULL) {
        return ERR_VAL;
    }
    if (!sys_mbox_valid(&conn->recvmbox)) {
        /* recvmbox already deleted */
        if (p != NULL) {
            tcp_recved(pcb, p->tot_len);
            pbuf_free(p);
        }
        return ERR_OK;
    }
    /* Unlike for UDP or RAW pcbs, don't check for available space
       using recv_avail since that could break the connection
       (data is already ACKed) */

    /* don't overwrite fatal errors! */
    NETCONN_SET_SAFE_ERR(conn, err);

    if (p != NULL) {
        len = p->tot_len;
    } else {
        len = 0;
    }

    if (sys_mbox_trypost(&conn->recvmbox, p) != ERR_OK) {
        /* don't deallocate p: it is presented to us later again from tcp_fasttmr! */
        return ERR_MEM;
    } else {
#if LWIP_SO_RCVBUF
        SYS_ARCH_INC(conn->recv_avail, len);
#endif /* LWIP_SO_RCVBUF */
        /* Register event with callback */
        API_EVENT(conn, NETCONN_EVT_RCVPLUS, len);
    }

    return ERR_OK;
}

/**
 * Poll callback function for TCP netconns.
 * Wakes up an application thread that waits for a connection to close
 * or data to be sent. The application thread then takes the
 * appropriate action to go on.
 *
 * Signals the conn->sem.
 * netconn_close waits for conn->sem if closing failed.
 *
 * @see tcp.h (struct tcp_pcb.poll) for parameters and return value
 */
static err_t
poll_tcp(void *arg, struct tcp_pcb *pcb)
{
    struct netconn *conn = (struct netconn *)arg;

    LWIP_UNUSED_ARG(pcb);
    LWIP_ASSERT("conn != NULL", (conn != NULL));

    if (conn->state == NETCONN_WRITE) {
        do_writemore(conn);
    } else if (conn->state == NETCONN_CLOSE) {
        do_close_internal(conn);
    }
    /* @todo: implement connect timeout here? */

    /* Did a nonblocking write fail before? Then check available write-space. */
    if (conn->flags & NETCONN_FLAG_CHECK_WRITESPACE) {
        /* If the queued byte- or pbuf-count drops below the configured low-water limit,
           let select mark this pcb as writable again. */
        if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT) &&
                (tcp_sndqueuelen(conn->pcb.tcp) < TCP_SNDQUEUELOWAT)) {
            conn->flags &= ~NETCONN_FLAG_CHECK_WRITESPACE;
            API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
        }
    }

    return ERR_OK;
}

/**
 * Sent callback function for TCP netconns.
 * Signals the conn->sem and calls API_EVENT.
 * netconn_write waits for conn->sem if send buffer is low.
 *
 * @see tcp.h (struct tcp_pcb.sent) for parameters and return value
 */
static err_t
sent_tcp(void *arg, struct tcp_pcb *pcb, u16_t len)
{
    struct netconn *conn = (struct netconn *)arg;

    LWIP_UNUSED_ARG(pcb);
    LWIP_ASSERT("conn != NULL", (conn != NULL));

    if (conn->state == NETCONN_WRITE) {
        do_writemore(conn);
    } else if (conn->state == NETCONN_CLOSE) {
        do_close_internal(conn);
    }

    if (conn) {
        /* If the queued byte- or pbuf-count drops below the configured low-water limit,
           let select mark this pcb as writable again. */
        if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT) &&
                (tcp_sndqueuelen(conn->pcb.tcp) < TCP_SNDQUEUELOWAT)) {
            conn->flags &= ~NETCONN_FLAG_CHECK_WRITESPACE;
            API_EVENT(conn, NETCONN_EVT_SENDPLUS, len);
        }
    }

    return ERR_OK;
}

/**
 * Error callback function for TCP netconns.
 * Signals conn->sem, posts to all conn mboxes and calls API_EVENT.
 * The application thread has then to decide what to do.
 *
 * @see tcp.h (struct tcp_pcb.err) for parameters
 */
static void
err_tcp(void *arg, err_t err)
{
    struct netconn *conn;
    enum netconn_state old_state;
    SYS_ARCH_DECL_PROTECT(lev);

    conn = (struct netconn *)arg;
    LWIP_ASSERT("conn != NULL", (conn != NULL));

    conn->pcb.tcp = NULL;

    /* no check since this is always fatal! */
    SYS_ARCH_PROTECT(lev);
    conn->last_err = err;
    SYS_ARCH_UNPROTECT(lev);

    /* reset conn->state now before waking up other threads */
    old_state = conn->state;
    conn->state = NETCONN_NONE;

    /* Notify the user layer about a connection error. Used to signal
       select. */
    API_EVENT(conn, NETCONN_EVT_ERROR, 0);
    /* Try to release selects pending on 'read' or 'write', too.
       They will get an error if they actually try to read or write. */
    API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
    API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);

    /* pass NULL-message to recvmbox to wake up pending recv */
    if (sys_mbox_valid(&conn->recvmbox)) {
        /* use trypost to prevent deadlock */
        sys_mbox_trypost(&conn->recvmbox, NULL);
    }
    /* pass NULL-message to acceptmbox to wake up pending accept */
    if (sys_mbox_valid(&conn->acceptmbox)) {
        /* use trypost to preven deadlock */
        sys_mbox_trypost(&conn->acceptmbox, NULL);
    }

    if ((old_state == NETCONN_WRITE) || (old_state == NETCONN_CLOSE) ||
            (old_state == NETCONN_CONNECT)) {
        /* calling do_writemore/do_close_internal is not necessary
           since the pcb has already been deleted! */
        int was_nonblocking_connect = IN_NONBLOCKING_CONNECT(conn);
        SET_NONBLOCKING_CONNECT(conn, 0);

        if (!was_nonblocking_connect) {
            /* set error return code */
            LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL);
            conn->current_msg->err = err;
            conn->current_msg = NULL;
            /* wake up the waiting task */
            sys_sem_signal(&conn->op_completed);
        }
    } else {
        LWIP_ASSERT("conn->current_msg == NULL", conn->current_msg == NULL);
    }
}

/**
 * Setup a tcp_pcb with the correct callback function pointers
 * and their arguments.
 *
 * @param conn the TCP netconn to setup
 */
static void
setup_tcp(struct netconn *conn)
{
    struct tcp_pcb *pcb;

    pcb = conn->pcb.tcp;
    tcp_arg(pcb, conn);
    tcp_recv(pcb, recv_tcp);
    tcp_sent(pcb, sent_tcp);
    tcp_poll(pcb, poll_tcp, 4);
    tcp_err(pcb, err_tcp);
}

/**
 * Accept callback function for TCP netconns.
 * Allocates a new netconn and posts that to conn->acceptmbox.
 *
 * @see tcp.h (struct tcp_pcb_listen.accept) for parameters and return value
 */
static err_t
accept_function(void *arg, struct tcp_pcb *newpcb, err_t err)
{
    struct netconn *newconn;
    struct netconn *conn = (struct netconn *)arg;

    LWIP_DEBUGF(API_MSG_DEBUG, ("accept_function: newpcb->tate: %s\n", tcp_debug_state_str(newpcb->state)));

    if (!sys_mbox_valid(&conn->acceptmbox)) {
        LWIP_DEBUGF(API_MSG_DEBUG, ("accept_function: acceptmbox already deleted\n"));
        return ERR_VAL;
    }

    /* We have to set the callback here even though
     * the new socket is unknown. conn->socket is marked as -1. */
    newconn = netconn_alloc(conn->type, conn->callback);
    if (newconn == NULL) {
        return ERR_MEM;
    }
    newconn->pcb.tcp = newpcb;
    setup_tcp(newconn);
    /* no protection: when creating the pcb, the netconn is not yet known
       to the application thread */
    newconn->last_err = err;

    if (sys_mbox_trypost(&conn->acceptmbox, newconn) != ERR_OK) {
        /* When returning != ERR_OK, the pcb is aborted in tcp_process(),
           so do nothing here! */
        /* remove all references to this netconn from the pcb */
        struct tcp_pcb* pcb = newconn->pcb.tcp;
        tcp_arg(pcb, NULL);
        tcp_recv(pcb, NULL);
        tcp_sent(pcb, NULL);
        tcp_poll(pcb, NULL, 4);
        tcp_err(pcb, NULL);
        /* remove reference from to the pcb from this netconn */
        newconn->pcb.tcp = NULL;
        /* no need to drain since we know the recvmbox is empty. */
        sys_mbox_free(&newconn->recvmbox);
        sys_mbox_set_invalid(&newconn->recvmbox);
        netconn_free(newconn);
        return ERR_MEM;
    } else {
        /* Register event with callback */
        API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
    }

    return ERR_OK;
}
#endif /* LWIP_TCP */

/**
 * Create a new pcb of a specific type.
 * Called from do_newconn().
 *
 * @param msg the api_msg_msg describing the connection type
 * @return msg->conn->err, but the return value is currently ignored
 */
static void
pcb_new(struct api_msg_msg *msg)
{
    LWIP_ASSERT("pcb_new: pcb already allocated", msg->conn->pcb.tcp == NULL);

    /* Allocate a PCB for this connection */
    switch(NETCONNTYPE_GROUP(msg->conn->type)) {
#if LWIP_RAW
    case NETCONN_RAW:
        msg->conn->pcb.raw = raw_new(msg->msg.n.proto);
        if(msg->conn->pcb.raw == NULL) {
            msg->err = ERR_MEM;
            break;
        }
        raw_recv(msg->conn->pcb.raw, recv_raw, msg->conn);
        break;
#endif /* LWIP_RAW */
#if LWIP_UDP
    case NETCONN_UDP:
        msg->conn->pcb.udp = udp_new();
        if(msg->conn->pcb.udp == NULL) {
            msg->err = ERR_MEM;
            break;
        }
#if LWIP_UDPLITE
        if (msg->conn->type==NETCONN_UDPLITE) {
            udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_UDPLITE);
        }
#endif /* LWIP_UDPLITE */
        if (msg->conn->type==NETCONN_UDPNOCHKSUM) {
            udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_NOCHKSUM);
        }
        udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
        break;
#endif /* LWIP_UDP */
#if LWIP_TCP
    case NETCONN_TCP:
        msg->conn->pcb.tcp = tcp_new();
        if(msg->conn->pcb.tcp == NULL) {
            msg->err = ERR_MEM;
            break;
        }
        setup_tcp(msg->conn);
        break;
#endif /* LWIP_TCP */
    default:
        /* Unsupported netconn type, e.g. protocol disabled */
        msg->err = ERR_VAL;
        break;
    }
}
コード例 #27
0
/**
  * @brief serve tcp connection  
  * @param conn: pointer on connection structure 
  * @retval None
  */
void http_server_serve(struct netconn *conn) 
{
  struct netbuf *inbuf;
  err_t recv_err;
  char* buf;
  u16_t buflen;
  struct fs_file * file;
  
  /* Read the data from the port, blocking if nothing yet there. 
   We assume the request (the part we care about) is in one netbuf */
  recv_err = netconn_recv(conn, &inbuf);
  
  if (recv_err == ERR_OK)
  {
    if (netconn_err(conn) == ERR_OK) 
    {
      netbuf_data(inbuf, (void**)&buf, &buflen);
    
      /* Is this an HTTP GET command? (only check the first 5 chars, since
      there are other formats for GET, and we're keeping it very simple )*/
      if ((buflen >=5) && (strncmp(buf, "GET /", 5) == 0))
      {
        /* Check if request to get ST.gif */ 
        if (strncmp((char const *)buf,"GET /STM32F4xx_files/ST.gif",27)==0)
        {
          file = fs_open("/STM32F4xx_files/ST.gif"); 
          netconn_write(conn, (const unsigned char*)(file->data), (size_t)file->len, NETCONN_NOCOPY);
          fs_close(file);
        }   
        /* Check if request to get stm32.jpeg */
        else if (strncmp((char const *)buf,"GET /STM32F4xx_files/stm32.jpg",30)==0)
        {
          file = fs_open("/STM32F4xx_files/stm32.jpg"); 
          netconn_write(conn, (const unsigned char*)(file->data), (size_t)file->len, NETCONN_NOCOPY);
          fs_close(file);
        }
        else if (strncmp((char const *)buf,"GET /STM32F4xx_files/logo.jpg", 29) == 0)                                           
        {
          /* Check if request to get ST logo.jpg */
          file = fs_open("/STM32F4xx_files/logo.jpg"); 
          netconn_write(conn, (const unsigned char*)(file->data), (size_t)file->len, NETCONN_NOCOPY);
          fs_close(file);
        }
        else if(strncmp(buf, "GET /STM32F4xxTASKS.html", 24) == 0)
        {
           /* Load dynamic page */
           DynWebPage(conn);
        }
        else if((strncmp(buf, "GET /STM32F4xx.html", 19) == 0)||(strncmp(buf, "GET / ", 6) == 0)) 
        {
          /* Load STM32F4x7 page */
          file = fs_open("/STM32F4xx.html"); 
          netconn_write(conn, (const unsigned char*)(file->data), (size_t)file->len, NETCONN_NOCOPY);
          fs_close(file);
        }
        else 
        {
          /* Load Error page */
          file = fs_open("/404.html"); 
          netconn_write(conn, (const unsigned char*)(file->data), (size_t)file->len, NETCONN_NOCOPY);
          fs_close(file);
        }
      }      
    }
  }
  /* Close the connection (server closes in HTTP) */
  netconn_close(conn);
  
  /* Delete the buffer (netconn_recv gives us ownership,
   so we have to make sure to deallocate the buffer) */
  netbuf_delete(inbuf);
}
コード例 #28
0
ファイル: main.c プロジェクト: waynenb/mcuoneclipse
static void LwipInitTask(void* pvArguments) {
    err_t err;
  struct netif fsl_netif0;
  ip_addr_t fsl_netif0_ipaddr, fsl_netif0_netmask, fsl_netif0_gw;

  char msg[] = "This is my message";

  (void)pvArguments;

  // Init lwip stack
  tcpip_init(NULL,NULL);
  printf("%s: lwip init called ..\n", __FUNCTION__);

  // Setup IP Config for DHCP ...
  IP4_ADDR(&fsl_netif0_ipaddr, 0,0,0,0);
  IP4_ADDR(&fsl_netif0_netmask, 0,0,0,0);
  IP4_ADDR(&fsl_netif0_gw, 0,0,0,0);

  /* Add a network interface to the list of lwIP netifs. */
  netif_add(&fsl_netif0, &fsl_netif0_ipaddr, &fsl_netif0_netmask, &fsl_netif0_gw, NULL, ethernetif_init, ethernet_input);
  /* Set the network interface as the default network interface. */
  netif_set_default(&fsl_netif0);
  /* obtain the IP address, default gateway and subnet mask by using DHCP*/
  err = dhcp_start(&fsl_netif0);

  printf("%s : Started DCHP request (%s)\n", __FUNCTION__, lwip_strerr(err));

  for(int i=0; i < DHCP_TIMEOUT && fsl_netif0.dhcp->state != DHCP_BOUND; i++) {
    printf("%s : Current DHCP State : %d\n", __FUNCTION__, fsl_netif0.dhcp->state);
    // Wait a second
    vTaskDelay(1000/portTICK_PERIOD_MS);
  }

  // Make it active ...
  netif_set_up(&fsl_netif0);

  printf("%s : Interface is up : %d\n", __FUNCTION__, fsl_netif0.dhcp->state);
  printf("%s : IP %s\n", __FUNCTION__, ipaddr_ntoa(&fsl_netif0.ip_addr));
  printf("%s : NM %s\n", __FUNCTION__, ipaddr_ntoa(&fsl_netif0.netmask));
  printf("%s : GW %s\n", __FUNCTION__, ipaddr_ntoa(&fsl_netif0.gw));

  if (fsl_netif0.dhcp->state == DHCP_BOUND) {
    // Send out some UDP data
    struct netconn* pConnection;

    // Create UDP connection
    pConnection = netconn_new(NETCONN_UDP);
    // Connect to local port
    err = netconn_bind(pConnection, IP_ADDR_ANY, 12345);
    printf("%s : Bound to IP_ADDR_ANY port 12345 (%s)\n", __FUNCTION__, lwip_strerr(err));

    err = netconn_connect(pConnection, IP_ADDR_BROADCAST, 12346 );
    printf("%s : Connected to IP_ADDR_BROADCAST port 12346 (%s)\n", __FUNCTION__, lwip_strerr(err));

    for(int i = 0; i < 10; i++ ){
      struct netbuf* buf = netbuf_new();
        void* data = netbuf_alloc(buf, sizeof(msg));

        memcpy (data, msg, sizeof (msg));
        err = netconn_send(pConnection, buf);
      printf("%s : Sending to IP_ADDR_BROADCAST port 12346 (%s)\n", __FUNCTION__, lwip_strerr(err));

        netbuf_delete(buf); // De-allocate packet buffer

        // Wait a second
      vTaskDelay(1000/portTICK_PERIOD_MS);
    }

    err = netconn_disconnect(pConnection);
    printf("%s : Disconnected from IP_ADDR_BROADCAST port 12346 (%s)\n", __FUNCTION__, lwip_strerr(err));

    err = netconn_delete(pConnection);
    printf("%s : Deleted connection (%s)\n", __FUNCTION__, lwip_strerr(err));
  }
  // Wait a second
  vTaskDelay(1000/portTICK_PERIOD_MS);

  /* finish the lease of the IP address */
  err = dhcp_release(&fsl_netif0);
  printf("%s : DHCP Release (%s)\n", __FUNCTION__, lwip_strerr(err));

  for(;;) {};
}
コード例 #29
0
ファイル: httpd.c プロジェクト: fabiobaltieri/nrf-ethernet
static void httpd_process(struct netconn *nc)
{
	struct netbuf *nb;
	char *buf;
	int ret;
	uint16_t len;
	char *url;
	char *hdr;
	char *data;
	int dlen;
	int i;
	struct path *path;

	ret = netconn_recv(nc, &nb);
	if (ret) {
		goto bailout;
	}

	netbuf_data(nb, (void **)&buf, &len);

	/* cut the initial "GET " */
	if (len > strlen(HTTP_GET) &&
	    strncmp(HTTP_GET, buf, strlen(HTTP_GET)) == 0) {
			url = buf + strlen(HTTP_GET);
			len -= strlen(HTTP_GET);
	} else if (len > strlen(HTTP_POST) &&
	    strncmp(HTTP_POST, buf, strlen(HTTP_POST)) == 0) {
			url = buf + strlen(HTTP_POST);
			len -= strlen(HTTP_POST);
	} else {
		goto bailout;
	}

	/* find the HTTP version and null terminate */
	for (i = 0; i < len - strlen(HTTP_VER); i++) {
		if (url[i] < ' ' || url[i] > '~')
			goto bailout;
		if (strncmp(HTTP_VER, url + i, strlen(HTTP_VER)) == 0) {
			url[i] = '\0';
			break;
		}
	}

	/* find header pointer and length */
	hdr = url + i + strlen(HTTP_VER);
	dlen = len - i - strlen(HTTP_VER);

	/* find end of headers and data length */
	for (i = 0; i < len - strlen(HTTP_BREAK); i++) {
		if (hdr[i] < ' ' || hdr[i] > '~')
			if (hdr[i] != '\r' && hdr[i] != '\n')
				goto bailout;
		if (strncmp(HTTP_BREAK, hdr + i, strlen(HTTP_BREAK)) == 0) {
			hdr[i] = '\0';
			break;
		}
	}

	/* find data pointer and length */
	data = hdr + i + strlen(HTTP_BREAK);
	dlen = dlen - i - strlen(HTTP_BREAK);

	blink(BLINK_RED, false);

	for (path = paths; path->path != NULL; path++)
		if (strcmp(path->path, url) == 0)
			break;

	net.nc = nc;
	net.count = 0;
	if (path->handler)
		path->handler(&net, url, hdr, data, dlen);
	else
		path_notfound(&net, url, hdr, data, dlen);

	netbuf_delete(nb);

	net_finalize(&net);

	netconn_close(nc);
	return;

bailout:
	netconn_close(nc);
	netbuf_delete(nb);
}
コード例 #30
-1
/**
 * Receive callback function for RAW netconns.
 * Doesn't 'eat' the packet, only references it and sends it to
 * conn->recvmbox
 *
 * @see raw.h (struct raw_pcb.recv) for parameters and return value
 */
static u8_t
recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p,
    struct ip_addr *addr)
{
  struct pbuf *q;
  struct netbuf *buf;
  struct netconn *conn;
#if LWIP_SO_RCVBUF
  int recv_avail;
#endif /* LWIP_SO_RCVBUF */

  LWIP_UNUSED_ARG(addr);
  conn = arg;

#if LWIP_SO_RCVBUF
  SYS_ARCH_GET(conn->recv_avail, recv_avail);
  if ((conn != NULL) && (conn->recvmbox != SYS_MBOX_NULL) &&
      ((recv_avail + (int)(p->tot_len)) <= conn->recv_bufsize)) {
#else  /* LWIP_SO_RCVBUF */
  if ((conn != NULL) && (conn->recvmbox != SYS_MBOX_NULL)) {
#endif /* LWIP_SO_RCVBUF */
    /* copy the whole packet into new pbufs */
    q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM);
    if(q != NULL) {
      if (pbuf_copy(q, p) != ERR_OK) {
        pbuf_free(q);
        q = NULL;
      }
    }

    if(q != NULL) {
      buf = memp_malloc(MEMP_NETBUF);
      if (buf == NULL) {
        pbuf_free(q);
        return 0;
      }

      buf->p = q;
      buf->ptr = q;
      buf->addr = &(((struct ip_hdr*)(q->payload))->src);
      buf->port = pcb->protocol;

      if (sys_mbox_trypost(conn->recvmbox, buf) != ERR_OK) {
        netbuf_delete(buf);
        return 0;
      } else {
        SYS_ARCH_INC(conn->recv_avail, q->tot_len);
        /* Register event with callback */
        API_EVENT(conn, NETCONN_EVT_RCVPLUS, q->tot_len);
      }
    }
  }

  return 0; /* do not eat the packet */
}
#endif /* LWIP_RAW*/

#if LWIP_UDP
/**
 * Receive callback function for UDP netconns.
 * Posts the packet to conn->recvmbox or deletes it on memory error.
 *
 * @see udp.h (struct udp_pcb.recv) for parameters
 */
static void
recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p,
   struct ip_addr *addr, u16_t port)
{
  struct netbuf *buf;
  struct netconn *conn;
#if LWIP_SO_RCVBUF
  int recv_avail;
#endif /* LWIP_SO_RCVBUF */

  LWIP_UNUSED_ARG(pcb); /* only used for asserts... */
  LWIP_ASSERT("recv_udp must have a pcb argument", pcb != NULL);
  LWIP_ASSERT("recv_udp must have an argument", arg != NULL);
  conn = arg;
  LWIP_ASSERT("recv_udp: recv for wrong pcb!", conn->pcb.udp == pcb);

#if LWIP_SO_RCVBUF
  SYS_ARCH_GET(conn->recv_avail, recv_avail);
  if ((conn == NULL) || (conn->recvmbox == SYS_MBOX_NULL) ||
      ((recv_avail + (int)(p->tot_len)) > conn->recv_bufsize)) {
#else  /* LWIP_SO_RCVBUF */
  if ((conn == NULL) || (conn->recvmbox == SYS_MBOX_NULL)) {
#endif /* LWIP_SO_RCVBUF */
    pbuf_free(p);
    return;
  }

  buf = memp_malloc(MEMP_NETBUF);
  if (buf == NULL) {
    pbuf_free(p);
    return;
  } else {
    buf->p = p;
    buf->ptr = p;
    buf->addr = addr;
    buf->port = port;
#if LWIP_NETBUF_RECVINFO
    {
      const struct ip_hdr* iphdr = ip_current_header();
      /* get the UDP header - always in the first pbuf, ensured by udp_input */
      const struct udp_hdr* udphdr = (void*)(((char*)iphdr) + IPH_LEN(iphdr));
      buf->toaddr = (struct ip_addr*)&iphdr->dest;
      buf->toport = udphdr->dest;
    }
#endif /* LWIP_NETBUF_RECVINFO */
  }

  if (sys_mbox_trypost(conn->recvmbox, buf) != ERR_OK) {
    netbuf_delete(buf);
    return;
  } else {
    SYS_ARCH_INC(conn->recv_avail, p->tot_len);
    /* Register event with callback */
    API_EVENT(conn, NETCONN_EVT_RCVPLUS, p->tot_len);
  }
}
#endif /* LWIP_UDP */

#if LWIP_TCP
/**
 * Receive callback function for TCP netconns.
 * Posts the packet to conn->recvmbox, but doesn't delete it on errors.
 *
 * @see tcp.h (struct tcp_pcb.recv) for parameters and return value
 */
static err_t
recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
  struct netconn *conn;
  u16_t len;

  LWIP_UNUSED_ARG(pcb);
  LWIP_ASSERT("recv_tcp must have a pcb argument", pcb != NULL);
  LWIP_ASSERT("recv_tcp must have an argument", arg != NULL);
  conn = arg;
  LWIP_ASSERT("recv_tcp: recv for wrong pcb!", conn->pcb.tcp == pcb);

  if ((conn == NULL) || (conn->recvmbox == SYS_MBOX_NULL)) {
    return ERR_VAL;
  }

  conn->err = err;
  if (p != NULL) {
    len = p->tot_len;
    SYS_ARCH_INC(conn->recv_avail, len);
  } else {
    len = 0;
  }

  if (sys_mbox_trypost(conn->recvmbox, p) != ERR_OK) {
    return ERR_MEM;
  } else {
    /* Register event with callback */
    API_EVENT(conn, NETCONN_EVT_RCVPLUS, len);
  }

  return ERR_OK;
}

/**
 * Poll callback function for TCP netconns.
 * Wakes up an application thread that waits for a connection to close
 * or data to be sent. The application thread then takes the
 * appropriate action to go on.
 *
 * Signals the conn->sem.
 * netconn_close waits for conn->sem if closing failed.
 *
 * @see tcp.h (struct tcp_pcb.poll) for parameters and return value
 */
static err_t
poll_tcp(void *arg, struct tcp_pcb *pcb)
{
  struct netconn *conn = arg;

  LWIP_UNUSED_ARG(pcb);
  LWIP_ASSERT("conn != NULL", (conn != NULL));

  if (conn->state == NETCONN_WRITE) {
    do_writemore(conn);
  } else if (conn->state == NETCONN_CLOSE) {
    do_close_internal(conn);
  }

  return ERR_OK;
}

/**
 * Sent callback function for TCP netconns.
 * Signals the conn->sem and calls API_EVENT.
 * netconn_write waits for conn->sem if send buffer is low.
 *
 * @see tcp.h (struct tcp_pcb.sent) for parameters and return value
 */
static err_t
sent_tcp(void *arg, struct tcp_pcb *pcb, u16_t len)
{
  struct netconn *conn = arg;

  LWIP_UNUSED_ARG(pcb);
  LWIP_ASSERT("conn != NULL", (conn != NULL));

  if (conn->state == NETCONN_WRITE) {
    LWIP_ASSERT("conn->pcb.tcp != NULL", conn->pcb.tcp != NULL);
    do_writemore(conn);
  } else if (conn->state == NETCONN_CLOSE) {
    do_close_internal(conn);
  }

  if (conn) {
    if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT)) {
      API_EVENT(conn, NETCONN_EVT_SENDPLUS, len);
    }
  }
  
  return ERR_OK;
}

/**
 * Error callback function for TCP netconns.
 * Signals conn->sem, posts to all conn mboxes and calls API_EVENT.
 * The application thread has then to decide what to do.
 *
 * @see tcp.h (struct tcp_pcb.err) for parameters
 */
static void
err_tcp(void *arg, err_t err)
{
  struct netconn *conn;

  conn = arg;
  LWIP_ASSERT("conn != NULL", (conn != NULL));

  conn->pcb.tcp = NULL;

  conn->err = err;
  if (conn->recvmbox != SYS_MBOX_NULL) {
    /* Register event with callback */
    API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
    sys_mbox_post(conn->recvmbox, NULL);
  }
  if (conn->op_completed != SYS_SEM_NULL && conn->state == NETCONN_CONNECT) {
    conn->state = NETCONN_NONE;
    sys_sem_signal(conn->op_completed);
  }
  if (conn->acceptmbox != SYS_MBOX_NULL) {
    /* Register event with callback */
    API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
    sys_mbox_post(conn->acceptmbox, NULL);
  }
  if ((conn->state == NETCONN_WRITE) || (conn->state == NETCONN_CLOSE)) {
    /* calling do_writemore/do_close_internal is not necessary
       since the pcb has already been deleted! */
    conn->state = NETCONN_NONE;
    /* wake up the waiting task */
    sys_sem_signal(conn->op_completed);
  }
}

/**
 * Setup a tcp_pcb with the correct callback function pointers
 * and their arguments.
 *
 * @param conn the TCP netconn to setup
 */
static void
setup_tcp(struct netconn *conn)
{
  struct tcp_pcb *pcb;

  pcb = conn->pcb.tcp;
  tcp_arg(pcb, conn);
  tcp_recv(pcb, recv_tcp);
  tcp_sent(pcb, sent_tcp);
  tcp_poll(pcb, poll_tcp, 4);
  tcp_err(pcb, err_tcp);
}

/**
 * Accept callback function for TCP netconns.
 * Allocates a new netconn and posts that to conn->acceptmbox.
 *
 * @see tcp.h (struct tcp_pcb_listen.accept) for parameters and return value
 */
static err_t
accept_function(void *arg, struct tcp_pcb *newpcb, err_t err)
{
  struct netconn *newconn;
  struct netconn *conn;

#if API_MSG_DEBUG
#if TCP_DEBUG
  tcp_debug_print_state(newpcb->state);
#endif /* TCP_DEBUG */
#endif /* API_MSG_DEBUG */
  conn = (struct netconn *)arg;

  LWIP_ERROR("accept_function: invalid conn->acceptmbox",
             conn->acceptmbox != SYS_MBOX_NULL, return ERR_VAL;);

  /* We have to set the callback here even though
   * the new socket is unknown. conn->socket is marked as -1. */
  newconn = netconn_alloc(conn->type, conn->callback);
  if (newconn == NULL) {
    return ERR_MEM;
  }
  newconn->pcb.tcp = newpcb;
  setup_tcp(newconn);
  newconn->err = err;

  if (sys_mbox_trypost(conn->acceptmbox, newconn) != ERR_OK) {
    /* When returning != ERR_OK, the connection is aborted in tcp_process(),
       so do nothing here! */
    newconn->pcb.tcp = NULL;
    netconn_free(newconn);
    return ERR_MEM;
  } else {
    /* Register event with callback */
    API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
  }

  return ERR_OK;
}
#endif /* LWIP_TCP */

/**
 * Create a new pcb of a specific type.
 * Called from do_newconn().
 *
 * @param msg the api_msg_msg describing the connection type
 * @return msg->conn->err, but the return value is currently ignored
 */
static err_t
pcb_new(struct api_msg_msg *msg)
{
   msg->conn->err = ERR_OK;

   LWIP_ASSERT("pcb_new: pcb already allocated", msg->conn->pcb.tcp == NULL);

   /* Allocate a PCB for this connection */
   switch(NETCONNTYPE_GROUP(msg->conn->type)) {
#if LWIP_RAW
   case NETCONN_RAW:
     msg->conn->pcb.raw = raw_new(msg->msg.n.proto);
     if(msg->conn->pcb.raw == NULL) {
       msg->conn->err = ERR_MEM;
       break;
     }
     raw_recv(msg->conn->pcb.raw, recv_raw, msg->conn);
     break;
#endif /* LWIP_RAW */
#if LWIP_UDP
   case NETCONN_UDP:
     msg->conn->pcb.udp = udp_new();
     if(msg->conn->pcb.udp == NULL) {
       msg->conn->err = ERR_MEM;
       break;
     }
#if LWIP_UDPLITE
     if (msg->conn->type==NETCONN_UDPLITE) {
       udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_UDPLITE);
     }
#endif /* LWIP_UDPLITE */
     if (msg->conn->type==NETCONN_UDPNOCHKSUM) {
       udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_NOCHKSUM);
     }
     udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
     break;
#endif /* LWIP_UDP */
#if LWIP_TCP
   case NETCONN_TCP:
     msg->conn->pcb.tcp = tcp_new();
     if(msg->conn->pcb.tcp == NULL) {
       msg->conn->err = ERR_MEM;
       break;
     }
     setup_tcp(msg->conn);
     break;
#endif /* LWIP_TCP */
   default:
     /* Unsupported netconn type, e.g. protocol disabled */
     msg->conn->err = ERR_VAL;
     break;
   }

  return msg->conn->err;
}