static int _transfer(struct in_addr *addr, uint8_t *wbuf, size_t wlen, uint8_t *rbuf, size_t rlen)
{
	struct sockaddr_in servaddr;
	socklen_t slen = sizeof(servaddr);
	int ret;

	int sockfd = open_udp_clientfd();

	make_sockaddr(&servaddr, addr, VIRTUAL_SWITCH_LISTEN_PORT);

	sendto(sockfd, wbuf, wlen, 0, (struct sockaddr *)&servaddr, slen);

	struct timeval tv = { 3, 0 };
	ret = recvfrom_timeout(sockfd, rbuf, rlen, NULL, NULL, &tv);

	if (ret <= 0) {
		hsb_critical("_transfer: get err pkt, len=%d\n", ret);
		close(sockfd);
		return -1;
	}

	close(sockfd);

	return ret;
}
static int virtual_switch_probe(void)
{
	struct sockaddr_in servaddr, devaddr;
	socklen_t slen = sizeof(servaddr);
	socklen_t devlen = sizeof(devaddr);
	uint8_t sbuf[64], rbuf[64];
	int ret;
	size_t count = 0;

	//hsb_debug("probe virtual switch\n");

	/* 1.create udp socket */
	int sockfd = open_udp_clientfd();

	/* 2.send broadcast packet, 192.168.2.255:19001 */
	if (get_broadcast_address(sockfd, &servaddr.sin_addr)) {
		close(sockfd);
		return -1;
	}

	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons(VIRTUAL_SWITCH_LISTEN_PORT);

	set_broadcast(sockfd, true);

	memset(sbuf, 0, sizeof(sbuf));
	count = 8;
	SET_CMD_FIELD(sbuf, 0, uint16_t, VS_CMD_DEVICE_DISCOVER);
	SET_CMD_FIELD(sbuf, 2, uint16_t, count);

	sendto(sockfd, sbuf, count, 0, (struct sockaddr *)&servaddr, slen);

	/* 3.wait for response in 1 second */
	struct timeval tv = { 3, 0 };
	
	do {
		ret = recvfrom_timeout(sockfd, rbuf, sizeof(rbuf), (struct sockaddr *)&devaddr, &devlen, &tv);
		if (ret < count) {
			hsb_critical("probe: get err pkt, len=%d\n", ret);
			continue;
		}

		count = 32;
		int cmd = GET_CMD_FIELD(rbuf, 0, uint16_t);
		int len = GET_CMD_FIELD(rbuf, 2, uint16_t);

		if (cmd != VS_CMD_DEVICE_DISCOVER_RESP || len != count) {
			hsb_critical("probe: get err pkt, cmd=%x, len=%d\n", cmd, len);
			continue;
		}

		_register_device(&devaddr.sin_addr, (VS_INFO_T *)(rbuf + 8));

	} while (tv.tv_sec > 0 && tv.tv_usec > 0);

	close(sockfd);
	//hsb_debug("probe virtual switch done\n");

	return 0;
}
Beispiel #3
0
static uint16_t recvfrom_udpinterrupt(struct uip_driver_s *dev, void *pvconn,
                                      void *pvpriv, uint16_t flags)
{
  struct recvfrom_s *pstate = (struct recvfrom_s *)pvpriv;

  nllvdbg("flags: %04x\n", flags);

  /* 'priv' might be null in some race conditions (?) */

  if (pstate)
    {
      /* If new data is available, then complete the read action. */

      if ((flags & UIP_NEWDATA) != 0)
        {
          /* Copy the data from the packet */

          recvfrom_newudpdata(dev, pstate);

          /* We are finished. */

          nllvdbg("UDP done\n");

          /* Don't allow any further UDP call backs. */

          pstate->rf_cb->flags   = 0;
          pstate->rf_cb->priv    = NULL;
          pstate->rf_cb->event   = NULL;

          /* Save the sender's address in the caller's 'from' location */

          recvfrom_udpsender(dev, pstate);

         /* Indicate that the data has been consumed */

          flags &= ~UIP_NEWDATA;

           /* Wake up the waiting thread, returning the number of bytes
           * actually read.
           */

          sem_post(&pstate->rf_sem);
        }

      /* No data has been received -- this is some other event... probably a
       * poll -- check for a timeout.
       */

#if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK)
      else if (recvfrom_timeout(pstate))
        {
          /* Yes.. the timeout has elapsed... do not allow any further
           * callbacks
           */

          nllvdbg("UDP timeout\n");

          /* Stop further callbacks */

          pstate->rf_cb->flags   = 0;
          pstate->rf_cb->priv    = NULL;
          pstate->rf_cb->event   = NULL;

          /* Report a timeout error */

          pstate->rf_result = -EAGAIN;

          /* Wake up the waiting thread */

          sem_post(&pstate->rf_sem);
        }
#endif /* CONFIG_NET_SOCKOPTS && !CONFIG_DISABLE_CLOCK */
    }
  return flags;
}
Beispiel #4
0
static uint16_t recvfrom_tcpinterrupt(struct uip_driver_s *dev, void *conn,
                                      void *pvpriv, uint16_t flags)
{
  struct recvfrom_s *pstate = (struct recvfrom_s *)pvpriv;

  nllvdbg("flags: %04x\n", flags);

  /* 'priv' might be null in some race conditions (?) */

  if (pstate)
    {
      /* If new data is available, then complete the read action. */

      if ((flags & UIP_NEWDATA) != 0)
        {
          /* Copy the data from the packet (saving any unused bytes from the
           * packet in the read-ahead buffer).
           */

          recvfrom_newtcpdata(dev, pstate);

          /* Save the sender's address in the caller's 'from' location */

          recvfrom_tcpsender(dev, pstate);

          /* Indicate that the data has been consumed and that an ACK
           * should be sent.
           */

          flags = (flags & ~UIP_NEWDATA) | UIP_SNDACK;

          /* Check for transfer complete.  We will consider the transfer
           * complete in own of two different ways, depending on the setting
           * of CONFIG_NET_TCP_RECVDELAY.
           *
           * 1) If CONFIG_NET_TCP_RECVDELAY == 0 then we will consider the
           *    TCP/IP transfer complete as soon as any data has been received.
           *    This is safe because if any additional data is received, it
           *    will be retained inthe TCP/IP read-ahead buffer until the
           *    next receive is performed.
           * 2) CONFIG_NET_TCP_RECVDELAY > 0 may be set to wait a little
           *    bit to determine if more data will be received.  You might
           *    do this if read-ahead buffereing is disabled and we want to
           *    minimize the loss of back-to-back packets.  In this case,
           *    the transfer is complete when either a) the entire user buffer 
           *    is full or 2) when the receive timeout occurs (below).
           */

#if CONFIG_NET_TCP_RECVDELAY > 0
          if (pstate->rf_buflen == 0)
#else
          if (pstate->rf_recvlen > 0)
#endif
            {
              nllvdbg("TCP resume\n");

              /* The TCP receive buffer is full.  Return now and don't allow
               * any further TCP call backs.
               */

              pstate->rf_cb->flags   = 0;
              pstate->rf_cb->priv    = NULL;
              pstate->rf_cb->event   = NULL;

              /* Wake up the waiting thread, returning the number of bytes
               * actually read.
               */

              sem_post(&pstate->rf_sem);
            }

            /* Reset the timeout.  We will want a short timeout to terminate
             * the TCP receive.
             */

#if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK)
            pstate->rf_starttime = clock_systimer();
#endif
        }

      /* Check for a loss of connection.
       *
       * UIP_CLOSE: The remote host has closed the connection
       * UIP_ABORT: The remote host has aborted the connection
       * UIP_TIMEDOUT: Connection aborted due to too many retransmissions.
       */

      else if ((flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0)
        {
          nllvdbg("error\n");

          /* Stop further callbacks */

          pstate->rf_cb->flags   = 0;
          pstate->rf_cb->priv    = NULL;
          pstate->rf_cb->event   = NULL;

          /* If the peer gracefully closed the connection, then return zero
           * (end-of-file).  Otherwise, report a not-connected error
           */

          if ((flags & UIP_CLOSE) != 0)
            {
              pstate->rf_result = 0;
            }
          else
            {
              pstate->rf_result = -ENOTCONN;
            }

          /* Wake up the waiting thread */

          sem_post(&pstate->rf_sem);
        }

      /* No data has been received -- this is some other event... probably a
       * poll -- check for a timeout.
       */

#if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK)
      else if (recvfrom_timeout(pstate))
        {
          /* Yes.. the timeout has elapsed... do not allow any further
           * callbacks
           */

          nllvdbg("TCP timeout\n");

          pstate->rf_cb->flags   = 0;
          pstate->rf_cb->priv    = NULL;
          pstate->rf_cb->event   = NULL;

          /* Report an error only if no data has been received. (If 
           * CONFIG_NET_TCP_RECVDELAY then rf_recvlen should always be
           * zero).
           */

#if CONFIG_NET_TCP_RECVDELAY > 0
          if (pstate->rf_recvlen == 0)
#endif
            {
              /* Report the timeout error */

              pstate->rf_result = -EAGAIN;
            }

          /* Wake up the waiting thread, returning either the error -EAGAIN
           * that signals the timeout event or the data received up to
           * the point tht the timeout occured (no error).
           */

          sem_post(&pstate->rf_sem);
        }
#endif /* CONFIG_NET_SOCKOPTS && !CONFIG_DISABLE_CLOCK */
    }
  return flags;
}