示例#1
0
int
sys_sem_wait_timeout(sys_sem_t sem, u32_t timeout)
{
    struct sswt_cb sswt_cb;

    sswt_cb.psem = &sem;
    sswt_cb.timeflag = 0;

    /* If timeout is zero, then just wait forever */
    if (timeout > 0)
        /* Create a timer and pass it the address of our flag */
        sys_timeout(timeout, sswt_handler, &sswt_cb);
    sys_sem_wait(sem);
    /* Was it a timeout? */
    if (sswt_cb.timeflag)
    {
        /* timeout */
        return 0;
    } else {
        /* Not a timeout. Remove timeout entry */
        sys_untimeout(sswt_handler, &sswt_cb);
        return 1;
    }

}
示例#2
0
文件: sntp.c 项目: cernekee/ocproxy
/**
 * Stop this module.
 */
void
sntp_stop(void)
{
  if (sntp_pcb != NULL) {
    sys_untimeout(sntp_request, NULL);
    udp_remove(sntp_pcb);
    sntp_pcb = NULL;
  }
}
示例#3
0
文件: ol_tcp.c 项目: MCRedJay/ling
static void send_cancel_deferred(outlet_t *ol)
{
	assert(ol->send_in_progress);
	ol->send_in_progress = 0;
	if (ol->send_timeout_set)
	{
		sys_untimeout(send_timeout_cb, ol);
		ol->send_timeout_set = 0;
	}
}
/*-------------------------------------------------------------------------
	Description:	
		This function is used to disable dhcp server.
	Arguments:
		None.		
		
	Return Value:
		None.
		
	Note:	
		
-------------------------------------------------------------------------*/
void DHCPS_Stop(void)
{
	/* Disable the dhcp server's service. */
	DhcpServer.Enable = 0;

	/* Stop the tick timer. */
	sys_untimeout(_DhcpTickHandle, NULL);

	/* Release the socket. */
	if(DhcpServer.Socket) udp_remove(DhcpServer.Socket);
	
	memset(&DhcpServer, 0, sizeof(DhcpServer));
}
示例#5
0
static void
close_handle(void)
{
  tftp_state.port = 0;
  ip_addr_set_any(0, &tftp_state.addr);

  if(tftp_state.last_data != NULL) {
    pbuf_free(tftp_state.last_data);
    tftp_state.last_data = NULL;
  }

  sys_untimeout(tftp_tmr, NULL);
  
  if (tftp_state.handle) {
    tftp_state.ctx->close(tftp_state.handle);
    tftp_state.handle = NULL;
    LWIP_DEBUGF(TFTP_DEBUG | LWIP_DBG_STATE, ("tftp: closing\n"));
  }
}
示例#6
0
/**
 * Schedule a delayed membership report for a group
 *
 * @param group the mld_group for which "delaying" membership report
 *              should be sent
 * @param maxresp the max resp delay provided in the query
 */
static void
mld6_delayed_report(struct mld_group *group, u16_t maxresp)
{
  /* Convert maxresp from milliseconds to tmr ticks */
  maxresp = maxresp / MLD6_TMR_INTERVAL;
  if (maxresp == 0) {
    maxresp = 1;
  }

#ifdef LWIP_RAND
  /* Randomize maxresp. (if LWIP_RAND is supported) */
  maxresp = LWIP_RAND() % maxresp;
  if (maxresp == 0) {
    maxresp = 1;
  }
#endif /* LWIP_RAND */

  /* Apply timer value if no report has been scheduled already. */
  if ((group->group_state == MLD6_GROUP_IDLE_MEMBER) ||
     ((group->group_state == MLD6_GROUP_DELAYING_MEMBER) &&
      ((group->timer == 0) || (maxresp < group->timer)))) {
        group->timer = maxresp;
	unsigned long curr_ticks = sys_arch_get_os_ticks() / MLD_TIMER_OFFSET;
	group->timer = group->timer + curr_ticks;

        group->group_state = MLD6_GROUP_DELAYING_MEMBER;
        struct mld_group* min_timeout_grp = lwip_get_min_timeout_mld_grp();

        if (min_timeout_grp &&
            (min_timeout_grp->timer) > (curr_ticks))  {
        if (group->timer <= min_timeout_grp->timer) {
        unsigned int new_timer_val = (min_timeout_grp->timer)
                         - curr_ticks;
        sys_untimeout(mld6_timer, NULL);
        sys_timeout(new_timer_val, mld6_timer, NULL);
     }
  }

  }
}
示例#7
0
static void ICACHE_FLASH_ATTR
ping_coarse_tmr(void *arg)
{
//	struct ping_msg *pingmsg = (struct ping_msg*)arg;
	struct ping_option *ping_opt= NULL;
	struct ping_resp pingresp;
	ip_addr_t ping_target;

	LWIP_ASSERT("ping_timeout: no pcb given!", pingmsg != NULL);
	ping_target.addr = pingmsg->ping_opt->ip;
	ping_opt = pingmsg->ping_opt;
	if (--pingmsg->sent_count != 0){
		pingmsg ->ping_sent = system_get_time();
		ping_send(pingmsg->ping_pcb, &ping_target);

		sys_timeout(PING_TIMEOUT_MS, ping_timeout, pingmsg);
		sys_timeout(pingmsg->coarse_time, ping_coarse_tmr, pingmsg);
	} else {
		uint32 delay = system_relative_time(pingmsg->ping_start);
		delay /= PING_COARSE;
		//ping_seq_num = 0;
		if (ping_opt->sent_function == NULL){
			os_printf("ping %d, timeout %d, total payload %d bytes, %d ms\n",
					pingmsg->max_count, pingmsg->timeout_count, PING_DATA_SIZE*(pingmsg->max_count - pingmsg->timeout_count),delay);
		} else {
			os_bzero(&pingresp, sizeof(struct ping_resp));
			pingresp.total_count = pingmsg->max_count;
			pingresp.timeout_count = pingmsg->timeout_count;
			pingresp.total_bytes = PING_DATA_SIZE*(pingmsg->max_count - pingmsg->timeout_count);
			pingresp.total_time = delay;
			pingresp.ping_err = 0;
		}
		sys_untimeout(ping_coarse_tmr, pingmsg);
		raw_remove(pingmsg->ping_pcb);
//		os_free(pingmsg);
		if (ping_opt->sent_function != NULL)
			ping_opt->sent_function(ping_opt,(uint8*)&pingresp);
	}
}
示例#8
0
/* Ping using the raw ip */
static u8_t ICACHE_FLASH_ATTR
ping_recv(void *arg, struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *addr)
{
  struct icmp_echo_hdr *iecho = NULL;
  static u16_t seqno = 0;
//  struct ping_msg *pingmsg = (struct ping_msg*)arg;

  LWIP_UNUSED_ARG(arg);
  LWIP_UNUSED_ARG(pcb);
  LWIP_UNUSED_ARG(addr);
  LWIP_ASSERT("p != NULL", p != NULL);

  if (pbuf_header( p, -PBUF_IP_HLEN)==0) {
    iecho = (struct icmp_echo_hdr *)p->payload;

    if ((iecho->id == PING_ID) && (iecho->seqno == htons(ping_seq_num)) && iecho->type == ICMP_ER) {
      LWIP_DEBUGF( PING_DEBUG, ("ping: recv "));
      ip_addr_debug_print(PING_DEBUG, addr);
      LWIP_DEBUGF( PING_DEBUG, (" %"U32_F" ms\n", (sys_now()-ping_time)));
	  if (iecho->seqno != seqno){
		  /* do some ping result processing */
		  {
			  struct ip_hdr *iphdr = NULL;
			  char ipaddrstr[16];
			  ip_addr_t source_ip;
			  sys_untimeout(ping_timeout, pingmsg);
			  os_bzero(&source_ip, sizeof(ip_addr_t));
			  os_bzero(ipaddrstr, sizeof(ipaddrstr));
			  uint32 delay = system_relative_time(pingmsg->ping_sent);
			  delay /= PING_COARSE;
			  iphdr = (struct ip_hdr*)((u8*)iecho - PBUF_IP_HLEN);
			  source_ip.addr = iphdr->src.addr;
			  ipaddr_ntoa_r(&source_ip,ipaddrstr, sizeof(ipaddrstr));
			  if (pingmsg->ping_opt->recv_function == NULL){
				  os_printf("recv %s: byte = %d, time = %d ms, seq = %d\n",ipaddrstr, PING_DATA_SIZE, delay, ntohs(iecho->seqno));
			  } else {
				  struct ping_resp pingresp;
				  os_bzero(&pingresp, sizeof(struct ping_resp));
				  pingresp.bytes = PING_DATA_SIZE;
				  pingresp.resp_time = delay;
				  pingresp.seqno = ntohs(iecho->seqno);
				  pingresp.ping_err = 0;
				  pingmsg->ping_opt->recv_function(pingmsg->ping_opt,(void*) &pingresp);
			  }
		  }
		  seqno = iecho->seqno;
	  }

      PING_RESULT(1);
      pbuf_free(p);
      return 1; /* eat the packet */
    }
//    } else if(iecho->type == ICMP_ECHO){
//        struct pbuf *q = NULL;
//        os_printf("receive ping request:seq=%d\n", ntohs(iecho->seqno));
//        q = pbuf_alloc(PBUF_IP, (u16_t)p->tot_len, PBUF_RAM);
//        if (q!=NULL) {
//            pbuf_copy(q, p);
//            iecho = (struct icmp_echo_hdr *)q->payload;
//            ping_prepare_er(iecho, q->tot_len);
//            raw_sendto(pcb, q, addr);
//            pbuf_free(q);
//        }
//        pbuf_free(p);
//        return 1;
//    }
  }

  return 0; /* don't eat the packet */
}
示例#9
0
/**
 * The main lwIP thread. This thread has exclusive access to lwIP core functions
 * (unless access to them is not locked). Other threads communicate with this
 * thread using message boxes.
 *
 * It also starts all the timers to make sure they are running in the right
 * thread context.
 *
 * @param arg unused argument
 */
static void
tcpip_thread(void *arg)
{
  struct tcpip_msg *msg;
  LWIP_UNUSED_ARG(arg);

#if IP_REASSEMBLY
  sys_timeout(IP_TMR_INTERVAL, ip_reass_timer, NULL);
#endif /* IP_REASSEMBLY */
#if LWIP_ARP
  sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
#endif /* LWIP_ARP */
#if LWIP_DHCP
  sys_timeout(DHCP_COARSE_TIMER_MSECS, dhcp_timer_coarse, NULL);
  sys_timeout(DHCP_FINE_TIMER_MSECS, dhcp_timer_fine, NULL);
#endif /* LWIP_DHCP */
#if LWIP_AUTOIP
  sys_timeout(AUTOIP_TMR_INTERVAL, autoip_timer, NULL);
#endif /* LWIP_AUTOIP */
#if LWIP_IGMP
  sys_timeout(IGMP_TMR_INTERVAL, igmp_timer, NULL);
#endif /* LWIP_IGMP */
#if LWIP_DNS
  sys_timeout(DNS_TMR_INTERVAL, dns_timer, NULL);
#endif /* LWIP_DNS */

  if (tcpip_init_done != NULL) {
    tcpip_init_done(tcpip_init_done_arg);
  }

  LOCK_TCPIP_CORE();
  while (1) {                          /* MAIN Loop */
    sys_mbox_fetch(mbox, (void *)&msg);
    switch (msg->type) {
#if LWIP_NETCONN
    case TCPIP_MSG_API:
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API message %p\n", (void *)msg));
      msg->msg.apimsg->function(&(msg->msg.apimsg->msg));
      break;
#endif /* LWIP_NETCONN */

    case TCPIP_MSG_INPKT:
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: PACKET %p\n", (void *)msg));
#if LWIP_ARP
      if (msg->msg.inp.netif->flags & NETIF_FLAG_ETHARP) {
        ethernet_input(msg->msg.inp.p, msg->msg.inp.netif);
      } else
#endif /* LWIP_ARP */
      { ip_input(msg->msg.inp.p, msg->msg.inp.netif);
      }
      memp_free(MEMP_TCPIP_MSG_INPKT, msg);
      break;

#if LWIP_NETIF_API
    case TCPIP_MSG_NETIFAPI:
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: Netif API message %p\n", (void *)msg));
      msg->msg.netifapimsg->function(&(msg->msg.netifapimsg->msg));
      break;
#endif /* LWIP_NETIF_API */

    case TCPIP_MSG_CALLBACK:
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK %p\n", (void *)msg));
      msg->msg.cb.f(msg->msg.cb.ctx);
      memp_free(MEMP_TCPIP_MSG_API, msg);
      break;

    case TCPIP_MSG_TIMEOUT:
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: TIMEOUT %p\n", (void *)msg));
      sys_timeout(msg->msg.tmo.msecs, msg->msg.tmo.h, msg->msg.tmo.arg);
      memp_free(MEMP_TCPIP_MSG_API, msg);
      break;
    case TCPIP_MSG_UNTIMEOUT:
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: UNTIMEOUT %p\n", (void *)msg));
      sys_untimeout(msg->msg.tmo.h, msg->msg.tmo.arg);
      memp_free(MEMP_TCPIP_MSG_API, msg);
      break;

    default:
      break;
    }
  }
}
示例#10
0
static void tcp_accept_untimeout(void *ctx)
{
	sys_untimeout(accept_timeout_cb, ctx);
}
示例#11
0
/**
 * The main lwIP thread. This thread has exclusive access to lwIP core functions
 * (unless access to them is not locked). Other threads communicate with this
 * thread using message boxes.
 *
 * It also starts all the timers to make sure they are running in the right
 * thread context.
 *
 * @param arg unused argument
 */
static void
tcpip_thread(void *arg)
{
  struct tcpip_msg *msg;
  LWIP_UNUSED_ARG(arg);

  if (tcpip_init_done != NULL) {
    tcpip_init_done(tcpip_init_done_arg);
  }

  LOCK_TCPIP_CORE();
  while (1) {                          /* MAIN Loop */
    UNLOCK_TCPIP_CORE();
    LWIP_TCPIP_THREAD_ALIVE();
    /* wait for a message, timeouts are processed while waiting */
    sys_timeouts_mbox_fetch(&mbox, (void **)&msg);
    LOCK_TCPIP_CORE();
    switch (msg->type) {
#if LWIP_NETCONN
    case TCPIP_MSG_API:
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API message %p\n", (void *)msg));
      msg->msg.apimsg->function(&(msg->msg.apimsg->msg));
      break;
#endif /* LWIP_NETCONN */

#if !LWIP_TCPIP_CORE_LOCKING_INPUT
    case TCPIP_MSG_INPKT:
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: PACKET %p\n", (void *)msg));
#if LWIP_ETHERNET
      if (msg->msg.inp.netif->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) {
        ethernet_input(msg->msg.inp.p, msg->msg.inp.netif);
      } else
#endif /* LWIP_ETHERNET */
      {
        ip_input(msg->msg.inp.p, msg->msg.inp.netif);
      }
      memp_free(MEMP_TCPIP_MSG_INPKT, msg);
      break;
#endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */

#if LWIP_NETIF_API
    case TCPIP_MSG_NETIFAPI:
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: Netif API message %p\n", (void *)msg));
      msg->msg.netifapimsg->function(&(msg->msg.netifapimsg->msg));
      break;
#endif /* LWIP_NETIF_API */

    case TCPIP_MSG_CALLBACK:
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK %p\n", (void *)msg));
      msg->msg.cb.function(msg->msg.cb.ctx);
      memp_free(MEMP_TCPIP_MSG_API, msg);
      break;

#if LWIP_TCPIP_TIMEOUT
    case TCPIP_MSG_TIMEOUT:
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: TIMEOUT %p\n", (void *)msg));
      sys_timeout(msg->msg.tmo.msecs, msg->msg.tmo.h, msg->msg.tmo.arg);
      memp_free(MEMP_TCPIP_MSG_API, msg);
      break;
    case TCPIP_MSG_UNTIMEOUT:
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: UNTIMEOUT %p\n", (void *)msg));
      sys_untimeout(msg->msg.tmo.h, msg->msg.tmo.arg);
      memp_free(MEMP_TCPIP_MSG_API, msg);
      break;
#endif /* LWIP_TCPIP_TIMEOUT */

    default:
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: %d\n", msg->type));
      LWIP_ASSERT("tcpip_thread: invalid message", 0);
      break;
    }
  }
}
示例#12
0
/** UDP recv callback for the sntp pcb */
static void
sntp_recv(void *arg, struct udp_pcb* pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
{
  u8_t mode;
  u8_t stratum;
  u32_t receive_timestamp[SNTP_RECEIVE_TIME_SIZE];
  err_t err;

  LWIP_UNUSED_ARG(arg);
  LWIP_UNUSED_ARG(pcb);

  /* packet received: stop retry timeout  */
  sys_untimeout(sntp_try_next_server, NULL);
  sys_untimeout(sntp_request, NULL);

  err = ERR_ARG;
#if SNTP_CHECK_RESPONSE >= 1
  /* check server address and port */
  if (((sntp_opmode != SNTP_OPMODE_POLL) || ip_addr_cmp(addr, &sntp_last_server_address)) &&
    (port == SNTP_PORT))
#else /* SNTP_CHECK_RESPONSE >= 1 */
  LWIP_UNUSED_ARG(addr);
  LWIP_UNUSED_ARG(port);
#endif /* SNTP_CHECK_RESPONSE >= 1 */
  {
    /* process the response */
    if (p->tot_len == SNTP_MSG_LEN) {
      pbuf_copy_partial(p, &mode, 1, SNTP_OFFSET_LI_VN_MODE);
      mode &= SNTP_MODE_MASK;
      /* if this is a SNTP response... */
      if (((sntp_opmode == SNTP_OPMODE_POLL) && (mode == SNTP_MODE_SERVER)) ||
          ((sntp_opmode == SNTP_OPMODE_LISTENONLY) && (mode == SNTP_MODE_BROADCAST))) {
        pbuf_copy_partial(p, &stratum, 1, SNTP_OFFSET_STRATUM);
        if (stratum == SNTP_STRATUM_KOD) {
          /* Kiss-of-death packet. Use another server or increase UPDATE_DELAY. */
          err = SNTP_ERR_KOD;
          LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_recv: Received Kiss-of-Death\n"));
        } else {
#if SNTP_CHECK_RESPONSE >= 2
          /* check originate_timetamp against sntp_last_timestamp_sent */
          u32_t originate_timestamp[2];
          pbuf_copy_partial(p, &originate_timestamp, 8, SNTP_OFFSET_ORIGINATE_TIME);
          if ((originate_timestamp[0] != sntp_last_timestamp_sent[0]) ||
              (originate_timestamp[1] != sntp_last_timestamp_sent[1]))
          {
            LWIP_DEBUGF(SNTP_DEBUG_WARN, ("sntp_recv: Invalid originate timestamp in response\n"));
          } else
#endif /* SNTP_CHECK_RESPONSE >= 2 */
          /* @todo: add code for SNTP_CHECK_RESPONSE >= 3 and >= 4 here */
          {
            /* correct answer */
            err = ERR_OK;
            pbuf_copy_partial(p, &receive_timestamp, SNTP_RECEIVE_TIME_SIZE * 4, SNTP_OFFSET_TRANSMIT_TIME);
          }
        }
      } else {
        LWIP_DEBUGF(SNTP_DEBUG_WARN, ("sntp_recv: Invalid mode in response: %"U16_F"\n", (u16_t)mode));
        /* wait for correct response */
        err = ERR_TIMEOUT;
      }
    } else {
      LWIP_DEBUGF(SNTP_DEBUG_WARN, ("sntp_recv: Invalid packet length: %"U16_F"\n", p->tot_len));
    }
  }
#if SNTP_CHECK_RESPONSE >= 1
  else {
示例#13
0
struct pbuf *
ip_reass(struct pbuf *p)
{
  struct pbuf *q;
  struct ip_hdr *fraghdr, *iphdr;
  u16_t offset, len;
  u16_t i;

  IPFRAG_STATS_INC(ip_frag.recv);

  iphdr = (struct ip_hdr *) ip_reassbuf;
  fraghdr = (struct ip_hdr *) p->payload;
  /* If ip_reasstmr is zero, no packet is present in the buffer, so we
     write the IP header of the fragment into the reassembly
     buffer. The timer is updated with the maximum age. */
  if (ip_reasstmr == 0) {
    LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass: new packet\n"));
    memcpy(iphdr, fraghdr, IP_HLEN);
    ip_reasstmr = IP_REASS_MAXAGE;
    sys_timeout(IP_REASS_TMO, ip_reass_timer, NULL);
    ip_reassflags = 0;
    /* Clear the bitmap. */
    memset(ip_reassbitmap, 0, sizeof(ip_reassbitmap));
  }

  /* Check if the incoming fragment matches the one currently present
     in the reasembly buffer. If so, we proceed with copying the
     fragment into the buffer. */
  if (ip_addr_cmp(&iphdr->src, &fraghdr->src) &&
      ip_addr_cmp(&iphdr->dest, &fraghdr->dest) &&
      IPH_ID(iphdr) == IPH_ID(fraghdr)) {
    LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass: matching old packet\n"));
    IPFRAG_STATS_INC(ip_frag.cachehit);
    /* Find out the offset in the reassembly buffer where we should
       copy the fragment. */
    len = ntohs(IPH_LEN(fraghdr)) - IPH_HL(fraghdr) * 4;
    offset = (ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) * 8;

    /* If the offset or the offset + fragment length overflows the
       reassembly buffer, we discard the entire packet. */
    if (offset > IP_REASS_BUFSIZE || offset + len > IP_REASS_BUFSIZE) {
      LWIP_DEBUGF(IP_REASS_DEBUG,
       ("ip_reass: fragment outside of buffer (%d:%d/%d).\n", offset,
        offset + len, IP_REASS_BUFSIZE));
      sys_untimeout(ip_reass_timer, NULL);
      ip_reasstmr = 0;
      goto nullreturn;
    }

    /* Copy the fragment into the reassembly buffer, at the right
       offset. */
    LWIP_DEBUGF(IP_REASS_DEBUG,
     ("ip_reass: copying with offset %d into %d:%d\n", offset,
      IP_HLEN + offset, IP_HLEN + offset + len));
    i = IPH_HL(fraghdr) * 4;
    copy_from_pbuf(p, &i, &ip_reassbuf[IP_HLEN + offset], len);

    /* Update the bitmap. */
    if (offset / (8 * 8) == (offset + len) / (8 * 8)) {
      LWIP_DEBUGF(IP_REASS_DEBUG,
       ("ip_reass: updating single byte in bitmap.\n"));
      /* If the two endpoints are in the same byte, we only update
         that byte. */
      ip_reassbitmap[offset / (8 * 8)] |=
    bitmap_bits[(offset / 8) & 7] &
    ~bitmap_bits[((offset + len) / 8) & 7];
    } else {
      /* If the two endpoints are in different bytes, we update the
         bytes in the endpoints and fill the stuff inbetween with
         0xff. */
      ip_reassbitmap[offset / (8 * 8)] |= bitmap_bits[(offset / 8) & 7];
      LWIP_DEBUGF(IP_REASS_DEBUG,
       ("ip_reass: updating many bytes in bitmap (%d:%d).\n",
        1 + offset / (8 * 8), (offset + len) / (8 * 8)));
      for (i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i) {
  ip_reassbitmap[i] = 0xff;
      }
      ip_reassbitmap[(offset + len) / (8 * 8)] |=
    ~bitmap_bits[((offset + len) / 8) & 7];
    }

    /* If this fragment has the More Fragments flag set to zero, we
       know that this is the last fragment, so we can calculate the
       size of the entire packet. We also set the
       IP_REASS_FLAG_LASTFRAG flag to indicate that we have received
       the final fragment. */

    if ((ntohs(IPH_OFFSET(fraghdr)) & IP_MF) == 0) {
      ip_reassflags |= IP_REASS_FLAG_LASTFRAG;
      ip_reasslen = offset + len;
      LWIP_DEBUGF(IP_REASS_DEBUG,
       ("ip_reass: last fragment seen, total len %d\n",
        ip_reasslen));
    }

    /* Finally, we check if we have a full packet in the buffer. We do
       this by checking if we have the last fragment and if all bits
       in the bitmap are set. */
    if (ip_reassflags & IP_REASS_FLAG_LASTFRAG) {
      /* Check all bytes up to and including all but the last byte in
         the bitmap. */
      for (i = 0; i < ip_reasslen / (8 * 8) - 1; ++i) {
  if (ip_reassbitmap[i] != 0xff) {
    LWIP_DEBUGF(IP_REASS_DEBUG,
     ("ip_reass: last fragment seen, bitmap %d/%d failed (%x)\n",
      i, ip_reasslen / (8 * 8) - 1, ip_reassbitmap[i]));
    goto nullreturn;
  }
      }
      /* Check the last byte in the bitmap. It should contain just the
         right amount of bits. */
      if (ip_reassbitmap[ip_reasslen / (8 * 8)] !=
    (u8_t) ~ bitmap_bits[ip_reasslen / 8 & 7]) {
  LWIP_DEBUGF(IP_REASS_DEBUG,
         ("ip_reass: last fragment seen, bitmap %d didn't contain %x (%x)\n",
    ip_reasslen / (8 * 8), ~bitmap_bits[ip_reasslen / 8 & 7],
    ip_reassbitmap[ip_reasslen / (8 * 8)]));
  goto nullreturn;
      }

      /* Pretend to be a "normal" (i.e., not fragmented) IP packet
         from now on. */
      ip_reasslen += IP_HLEN;

      IPH_LEN_SET(iphdr, htons(ip_reasslen));
      IPH_OFFSET_SET(iphdr, 0);
      IPH_CHKSUM_SET(iphdr, 0);
      IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN));

      /* If we have come this far, we have a full packet in the
         buffer, so we allocate a pbuf and copy the packet into it. We
         also reset the timer. */
      sys_untimeout(ip_reass_timer, NULL);
      ip_reasstmr = 0;
      pbuf_free(p);
      p = pbuf_alloc(PBUF_LINK, ip_reasslen, PBUF_POOL);
      if (p != NULL) {
  i = 0;
  for (q = p; q != NULL; q = q->next) {
    /* Copy enough bytes to fill this pbuf in the chain. The
       available data in the pbuf is given by the q->len
       variable. */
    LWIP_DEBUGF(IP_REASS_DEBUG,
     ("ip_reass: memcpy from %p (%d) to %p, %d bytes\n",
      (void *)&ip_reassbuf[i], i, q->payload,
      q->len > ip_reasslen - i ? ip_reasslen - i : q->len));
    memcpy(q->payload, &ip_reassbuf[i],
    q->len > ip_reasslen - i ? ip_reasslen - i : q->len);
    i += q->len;
  }
  IPFRAG_STATS_INC(ip_frag.fw);
      } else {
  IPFRAG_STATS_INC(ip_frag.memerr);
      }
      LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass: p %p\n", (void*)p));
      return p;
    }
  }

nullreturn:
  IPFRAG_STATS_INC(ip_frag.drop);
  pbuf_free(p);
  return NULL;
}
示例#14
0
/** UDP receive callback for the sntp pcb */
static void sntp_recv(void *arg, struct udp_pcb* pcb, struct pbuf *p, ip_addr_t *addr, u16_t port) {
    u8_t mode;
    u8_t stratum;
    u32_t receive_timestamp[SNTP_RECEIVE_TIME_SIZE];
    err_t err;

    LWIP_UNUSED_ARG(arg);
    LWIP_UNUSED_ARG(pcb);

    /* packet received: stop retry timeout  */
    sys_untimeout(sntp_try_next_server, NULL);
    sys_untimeout(sntp_request, NULL);

    err = ERR_ARG;
#if SNTP_CHECK_RESPONSE >= 1
    /* Check server address and port */
    if (ip_addr_cmp(addr, &sntp_last_server_address) && (port == SNTP_PORT))
#else /* SNTP_CHECK_RESPONSE >= 1 */
    LWIP_UNUSED_ARG(addr);
    LWIP_UNUSED_ARG(port);
#endif /* SNTP_CHECK_RESPONSE >= 1 */
    {
        /* Process the response */
        if (p->tot_len == SNTP_MSG_LEN) {
            pbuf_copy_partial(p, &mode, 1, SNTP_OFFSET_LI_VN_MODE);
            mode &= SNTP_MODE_MASK;
            /* If this is a SNTP response... */
            if ((mode == SNTP_MODE_SERVER) || (mode == SNTP_MODE_BROADCAST)) {
                pbuf_copy_partial(p, &stratum, 1, SNTP_OFFSET_STRATUM);
                if (stratum == SNTP_STRATUM_KOD) {
                    /* Kiss-of-death packet. Use another server or increase UPDATE_DELAY. */
                    err = SNTP_ERR_KOD;
                    LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_recv: Received Kiss-of-Death\n"));
                } else {
#if SNTP_CHECK_RESPONSE >= 2
                    /* check originate_timetamp against sntp_last_timestamp_sent */
                    u32_t originate_timestamp[2];
                    pbuf_copy_partial(p, &originate_timestamp, 8, SNTP_OFFSET_ORIGINATE_TIME);
                    if ((originate_timestamp[0] != sntp_last_timestamp_sent[0]) ||
                            (originate_timestamp[1] != sntp_last_timestamp_sent[1])) {
                        LWIP_DEBUGF(SNTP_DEBUG_WARN, ("sntp_recv: Invalid originate timestamp in response\n"));
                    } else
#endif /* SNTP_CHECK_RESPONSE >= 2 */
                        /* @todo: add code for SNTP_CHECK_RESPONSE >= 3 and >= 4 here */
                    {
                        /* Correct answer */
                        err = ERR_OK;
                        pbuf_copy_partial(p, &receive_timestamp, SNTP_RECEIVE_TIME_SIZE * 4, SNTP_OFFSET_RECEIVE_TIME);
                    }
                }
            } else {
                LWIP_DEBUGF(SNTP_DEBUG_WARN, ("sntp_recv: Invalid mode in response: %"U16_F"\n", (u16_t)mode));
            }
        } else {
            LWIP_DEBUGF(SNTP_DEBUG_WARN, ("sntp_recv: Invalid packet length: %"U16_F"\n", p->tot_len));
        }
    }
    pbuf_free(p);

    if (err == ERR_OK) {
        /* Correct response, reset retry timeout */
        SNTP_RESET_RETRY_TIMEOUT();

        sntp_process(receive_timestamp);

        /* Set up timeout for next request */
        sys_timeout((u32_t)SNTP_UPDATE_DELAY, sntp_request, NULL);
        LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_recv: Scheduled next time request: %"U32_F" ms\n", (u32_t)SNTP_UPDATE_DELAY));
    } else if (err == SNTP_ERR_KOD) {
        /* Kiss-of-death packet. Use another server or increase UPDATE_DELAY. */
        sntp_try_next_server(NULL);
    } else {
        /* Another error, try the same server again */
        sntp_retry(NULL);
    }
}
示例#15
0
文件: tcpip.c 项目: ChenZewei/acoral
/**
 * The main lwIP thread. This thread has exclusive access to lwIP core functions
 * (unless access to them is not locked). Other threads communicate with this
 * thread using message boxes.
 *
 * It also starts all the timers to make sure they are running in the right
 * thread context.
 *
 * @param arg unused argument
 */
static void
tcpip_thread(void *arg)
{
  struct tcpip_msg *msg;
  LWIP_UNUSED_ARG(arg);

#if IP_REASSEMBLY
  sys_timeout(IP_TMR_INTERVAL, ip_reass_timer, NULL);
#endif /* IP_REASSEMBLY */
#if LWIP_ARP
  sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
#endif /* LWIP_ARP */
#if LWIP_DHCP
  sys_timeout(DHCP_COARSE_TIMER_MSECS, dhcp_timer_coarse, NULL);
  sys_timeout(DHCP_FINE_TIMER_MSECS, dhcp_timer_fine, NULL);
#endif /* LWIP_DHCP */
#if LWIP_AUTOIP
  sys_timeout(AUTOIP_TMR_INTERVAL, autoip_timer, NULL);
#endif /* LWIP_AUTOIP */
#if LWIP_IGMP
  sys_timeout(IGMP_TMR_INTERVAL, igmp_timer, NULL);
#endif /* LWIP_IGMP */
#if LWIP_DNS
  sys_timeout(DNS_TMR_INTERVAL, dns_timer, NULL);
#endif /* LWIP_DNS */

  if (tcpip_init_done != NULL) {
    tcpip_init_done(tcpip_init_done_arg);
  }

  LOCK_TCPIP_CORE();
  while (1) {                          /* MAIN Loop */
    sys_mbox_fetch(mbox, (void *)&msg);
    // teset by pegasus
    //if (msg->msg.apimsg->msg.msg.w.dataptr == &htmldata)
    //  acoral_print("\nhtmldata:\n");//*,msg->msg.apimsg->msg.msg.w.dataptr);
    switch (msg->type) {
#if LWIP_NETCONN
    case TCPIP_MSG_API:
      //lwip_printf("\r\n1\r\n");
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API message %p\n", (void *)msg));
      msg->msg.apimsg->function(&(msg->msg.apimsg->msg));
      //acoral_print("\r\n%x\r\n",msg->msg.apimsg->function);

      //acoral_print("MSG_API:%s",msg->msg.apimsg->msg.w.dataptr);
      
      break;
#endif /* LWIP_NETCONN */

    case TCPIP_MSG_INPKT:
      //lwip_printf("\r\n2\r\n");
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: PACKET %p\n", (void *)msg));
#if LWIP_ARP
      if (msg->msg.inp.netif->flags & NETIF_FLAG_ETHARP) {
        ethernet_input(msg->msg.inp.p, msg->msg.inp.netif);
      } else
#endif /* LWIP_ARP */
      {//acoral_print("\nip_input:2==2\n");
       ip_input(msg->msg.inp.p, msg->msg.inp.netif);
      }
      memp_free(MEMP_TCPIP_MSG_INPKT, msg);
      break;

#if LWIP_NETIF_API
    case TCPIP_MSG_NETIFAPI:
      //lwip_printf("\r\n3\r\n");
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: Netif API message %p\n", (void *)msg));
      msg->msg.netifapimsg->function(&(msg->msg.netifapimsg->msg));
      break;
#endif /* LWIP_NETIF_API */

    case TCPIP_MSG_CALLBACK:
      //lwip_printf("\r\n4\r\n");
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK %p\n", (void *)msg));
      msg->msg.cb.f(msg->msg.cb.ctx);
      memp_free(MEMP_TCPIP_MSG_API, msg);
      break;

    case TCPIP_MSG_TIMEOUT:
      //lwip_printf("\r\n5\r\n");
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: TIMEOUT %p\n", (void *)msg));

      if(msg->msg.tmo.msecs != 0xffffffff)
        sys_timeout (msg->msg.tmo.msecs, msg->msg.tmo.h, msg->msg.tmo.arg);
      else
        sys_untimeout (msg->msg.tmo.h, msg->msg.tmo.arg);
      memp_free(MEMP_TCPIP_MSG_API, msg);
      break;

    default:
      //lwip_printf("\r\n=======================\r\n");
      pbuf_free(msg->msg.inp.p);
      break;
    }
  }
}
示例#16
0
文件: tcpip.c 项目: wosayttn/aos
/**
 * The main lwIP thread. This thread has exclusive access to lwIP core functions
 * (unless access to them is not locked). Other threads communicate with this
 * thread using message boxes.
 *
 * It also starts all the timers to make sure they are running in the right
 * thread context.
 *
 * @param arg unused argument
 */
static void
tcpip_thread(void *arg)
{
  struct tcpip_msg *msg;
  LWIP_UNUSED_ARG(arg);

  if (tcpip_init_done != NULL) {
    tcpip_init_done(tcpip_init_done_arg);
  }

  LOCK_TCPIP_CORE();
  while (1) {                          /* MAIN Loop */
    UNLOCK_TCPIP_CORE();
    LWIP_TCPIP_THREAD_ALIVE();
    /* wait for a message, timeouts are processed while waiting */
    TCPIP_MBOX_FETCH(&mbox, (void **)&msg);
    LOCK_TCPIP_CORE();
    if (msg == NULL) {
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: NULL\n"));
      LWIP_ASSERT("tcpip_thread: invalid message", 0);
      continue;
    }
    switch (msg->type) {
#if !LWIP_TCPIP_CORE_LOCKING
    case TCPIP_MSG_API:
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API message %p\n", (void *)msg));
      msg->msg.api_msg.function(msg->msg.api_msg.msg);
      break;
    case TCPIP_MSG_API_CALL:
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API CALL message %p\n", (void *)msg));
      msg->msg.api_call.arg->err = msg->msg.api_call.function(msg->msg.api_call.arg);
      sys_sem_signal(msg->msg.api_call.sem);
      break;
#endif /* !LWIP_TCPIP_CORE_LOCKING */

#if !LWIP_TCPIP_CORE_LOCKING_INPUT
    case TCPIP_MSG_INPKT:
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: PACKET %p\n", (void *)msg));
      msg->msg.inp.input_fn(msg->msg.inp.p, msg->msg.inp.netif);
      memp_free(MEMP_TCPIP_MSG_INPKT, msg);
      break;
#endif /* !LWIP_TCPIP_CORE_LOCKING_INPUT */

#if LWIP_TCPIP_TIMEOUT && LWIP_TIMERS
    case TCPIP_MSG_TIMEOUT:
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: TIMEOUT %p\n", (void *)msg));
      sys_timeout(msg->msg.tmo.msecs, msg->msg.tmo.h, msg->msg.tmo.arg);
      memp_free(MEMP_TCPIP_MSG_API, msg);
      break;
    case TCPIP_MSG_UNTIMEOUT:
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: UNTIMEOUT %p\n", (void *)msg));
      sys_untimeout(msg->msg.tmo.h, msg->msg.tmo.arg);
      memp_free(MEMP_TCPIP_MSG_API, msg);
      break;
#endif /* LWIP_TCPIP_TIMEOUT && LWIP_TIMERS */

    case TCPIP_MSG_CALLBACK:
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK %p\n", (void *)msg));
      msg->msg.cb.function(msg->msg.cb.ctx);
      memp_free(MEMP_TCPIP_MSG_API, msg);
      break;

    case TCPIP_MSG_CALLBACK_STATIC:
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK_STATIC %p\n", (void *)msg));
      msg->msg.cb.function(msg->msg.cb.ctx);
      break;
#ifdef LWIP_NETIF_DRV
    case TCPIP_MSG_DRV:
      LWIP_DEBUGF(NETIF_DEBUG, ("tcpip_thread: DRV %p\n", (void *)msg));
      msg->msg.drv.drv_fn(msg->msg.drv.netif, msg->msg.drv.event);
      memp_free(MEMP_NETIF_DRV_MSG, msg);
      break;
#endif
    default:
      LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: %d\n", msg->type));
      LWIP_ASSERT("tcpip_thread: invalid message", 0);
      break;
    }
  }
}