Beispiel #1
0
/**
 * Delete the pcb inside a netconn.
 * Called from netconn_delete.
 *
 * @param msg the api_msg_msg pointing to the connection
 */
void
lwip_netconn_do_delconn(struct api_msg_msg *msg)
{
  /* @todo TCP: abort running write/connect? */
 if ((msg->conn->state != NETCONN_NONE) &&
     (msg->conn->state != NETCONN_LISTEN) &&
     (msg->conn->state != NETCONN_CONNECT)) {
    /* this only happens for TCP netconns */
    LWIP_ASSERT("NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP",
                NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP);
    msg->err = ERR_INPROGRESS;
  } else {
    LWIP_ASSERT("blocking connect in progress",
      (msg->conn->state != NETCONN_CONNECT) || IN_NONBLOCKING_CONNECT(msg->conn));
    /* Drain and delete mboxes */
    netconn_drain(msg->conn);

    if (msg->conn->pcb.tcp != NULL) {

      switch (NETCONNTYPE_GROUP(msg->conn->type)) {
#if LWIP_RAW
      case NETCONN_RAW:
        raw_remove(msg->conn->pcb.raw);
        break;
#endif /* LWIP_RAW */
#if LWIP_UDP
      case NETCONN_UDP:
        msg->conn->pcb.udp->recv_arg = NULL;
        udp_remove(msg->conn->pcb.udp);
        break;
#endif /* LWIP_UDP */
#if LWIP_TCP
      case NETCONN_TCP:
        LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL &&
          msg->conn->write_offset == 0);
        msg->conn->state = NETCONN_CLOSE;
        msg->msg.sd.shut = NETCONN_SHUT_RDWR;
        msg->conn->current_msg = msg;
        lwip_netconn_do_close_internal(msg->conn);
        /* API_EVENT is called inside lwip_netconn_do_close_internal, before releasing
           the application thread, so we can return at this point! */
        return;
#endif /* LWIP_TCP */
      default:
        break;
      }
      msg->conn->pcb.tcp = NULL;
    }
    /* tcp netconns don't come here! */

    /* @todo: this lets select make the socket readable and writable,
       which is wrong! errfd instead? */
    API_EVENT(msg->conn, NETCONN_EVT_RCVPLUS, 0);
    API_EVENT(msg->conn, NETCONN_EVT_SENDPLUS, 0);
  }
  if (sys_sem_valid(&msg->conn->op_completed)) {
    sys_sem_signal(&msg->conn->op_completed);
  }
}
static void
do_delconn(struct api_msg_msg *msg)
{
  if (msg->conn->pcb.tcp != NULL) {
    switch (msg->conn->type) {
#if LWIP_RAW
    case NETCONN_RAW:
      raw_remove(msg->conn->pcb.raw);
      break;
#endif
#if LWIP_UDP
    case NETCONN_UDPLITE:
      /* FALLTHROUGH */
    case NETCONN_UDPNOCHKSUM:
      /* FALLTHROUGH */
    case NETCONN_UDP:
      msg->conn->pcb.udp->recv_arg = NULL;
      udp_remove(msg->conn->pcb.udp);
      break;
#endif /* LWIP_UDP */
#if LWIP_TCP      
    case NETCONN_TCP:
      if (msg->conn->pcb.tcp->state == LISTEN) {
  tcp_arg(msg->conn->pcb.tcp, NULL);
  tcp_accept(msg->conn->pcb.tcp, NULL);  
  tcp_close(msg->conn->pcb.tcp);
      } else {
  tcp_arg(msg->conn->pcb.tcp, NULL);
  tcp_sent(msg->conn->pcb.tcp, NULL);
  tcp_recv(msg->conn->pcb.tcp, NULL);  
  tcp_poll(msg->conn->pcb.tcp, NULL, 0);
  tcp_err(msg->conn->pcb.tcp, NULL);
  if (tcp_close(msg->conn->pcb.tcp) != ERR_OK) {
    tcp_abort(msg->conn->pcb.tcp);
  }
      }
#endif
    default:  
    break;
    }
  }
  /* Trigger select() in socket layer */
  if (msg->conn->callback)
  {
      (*msg->conn->callback)(msg->conn, NETCONN_EVT_RCVPLUS, 0);
      (*msg->conn->callback)(msg->conn, NETCONN_EVT_SENDPLUS, 0);
  }
  
  if (msg->conn->mbox != SYS_MBOX_NULL) {
    sys_mbox_post(msg->conn->mbox, NULL);
  }
}
Beispiel #3
0
static void raw_ip_close(struct socket * sock)
{
	/* deque and free all enqueued data before closing */
	sock_dequeue_data_all(sock, raw_ip_recv_free);

	if (sock->pcb)
		raw_remove(sock->pcb);
	if (sock->buf)
		sock_free_buf(sock->buf);

	/* mark it as unused */
	sock->ops = NULL;
}
Beispiel #4
0
static void
ping_thread(void *arg)
{
	struct raw_pcb *raw;

	if (!(raw = raw_new(IP_PROTO_ICMP))) return;

	raw_recv(raw,ping_recv,NULL);

	while (1) {
		printf("ping send\n");
		ping_send(raw,&ping_addr);
		sleep(1);
	}
	/* Never reaches this */
	raw_remove(raw);
}
Beispiel #5
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);
	}
}
Beispiel #6
0
/**
 * Delete the pcb inside a netconn.
 * Called from netconn_delete.
 *
 * @param msg the api_msg_msg pointing to the connection
 */
void
do_delconn(struct api_msg_msg *msg)
{
  if (msg->conn->pcb.tcp != NULL) {
    switch (NETCONNTYPE_GROUP(msg->conn->type)) {
#if LWIP_RAW
    case NETCONN_RAW:
      raw_remove(msg->conn->pcb.raw);
      break;
#endif /* LWIP_RAW */
#if LWIP_UDP
    case NETCONN_UDP:
      msg->conn->pcb.udp->recv_arg = NULL;
      udp_remove(msg->conn->pcb.udp);
      break;
#endif /* LWIP_UDP */
#if LWIP_TCP
    case NETCONN_TCP:
      msg->conn->state = NETCONN_CLOSE;
      do_close_internal(msg->conn);
      /* API_EVENT is called inside do_close_internal, before releasing
         the application thread, so we can return at this point! */
      return;
#endif /* LWIP_TCP */
    default:
      break;
    }
  }
  /* tcp netconns don't come here! */

  /* Trigger select() in socket layer. This send should something else so the
     errorfd is set, not the read and write fd! */
  API_EVENT(msg->conn, NETCONN_EVT_RCVPLUS, 0);
  API_EVENT(msg->conn, NETCONN_EVT_SENDPLUS, 0);

  if (msg->conn->op_completed != SYS_SEM_NULL) {
    sys_sem_signal(msg->conn->op_completed);
  }
}
 int32_t MTD_FLASHMEM ICMP::ping(IPAddress const& dest)
 {       
     static uint32_t const TIMEOUT        = 4000;
     static int32_t const TIMEOUT_RESULT  = -1;
 
     uint32_t result = TIMEOUT_RESULT;
             
     // generate seq
     m_waitingSeq++;
     
     // prepare packet to send
     pbuf* hdrbuf = pbuf_alloc(PBUF_IP, sizeof(icmp_echo_hdr), PBUF_RAM);
     icmp_echo_hdr* hdr = (icmp_echo_hdr*)hdrbuf->payload;
     hdr->type   = ICMP_ECHO;
     hdr->code   = 0;
     hdr->chksum = 0;
     hdr->id     = htons(m_waitingID);
     hdr->seqno  = htons(m_waitingSeq);
     hdr->chksum = inet_chksum((uint16_t*)hdr, sizeof(icmp_echo_hdr));
     
     // send Echo request
     raw_pcb* pcb = raw_new(IP_PROTO_ICMP);
     raw_recv(pcb, ICMP::raw_recv_fn, this);
     raw_bind(pcb, IP_ADDR_ANY);            
     
     ip_addr_t addr = dest.get_ip_addr_t();
     raw_sendto(pcb, hdrbuf, &addr);
     pbuf_free(hdrbuf);
     
     uint32_t t1 = micros();
     if (m_queue.receive(TIMEOUT))
         result = (micros() - t1);
             
     raw_remove(pcb);
     
     return result;            
 }
 void remove(const E elem)   			{ raw_remove((const void*) elem);                    }
Beispiel #9
0
cmd_state_t cmd_ping(int argc, char* argv[], void* ctx)
{
        static enum {
                INIT,
                PING,
                WAIT_REPLY
        } state = INIT;

        struct ping_info_t *ping_info = &INFO;
        static struct raw_pcb *pcb;

        switch (state) {
        case INIT:
                if (init_ping_info(argc, argv, ping_info) != 0) {
                        printk("Usage: ping [-c count] [-i interval] "  \
                               "[-s packetsize]\n            " \
                               "[-w deadline] [-q] destination\n");
                        return CMD_DONE;
                }

                if (!(pcb = raw_new(IP_PROTO_ICMP))) {
                        printk("could not allocate pcb\n");
                        state = INIT;
                        return CMD_DONE;
                }
                raw_recv(pcb, ping_recv, ping_info);
                raw_bind(pcb, IP_ADDR_ANY);

                printk("PING %s %d(%d) bytes of data\n",
                       ip2str(ping_info->destination),
                       ping_info->data_size,
                       ping_info->size);
                state = PING;
                /* fall through */

        case PING:
                if (!netif_is_up(netif_default)) {
                        printk("netif is down\n");
                        raw_remove(pcb);
                        state = INIT;
                        return CMD_DONE;
                }

                if (ping_info->count && ping_info->num_tx == ping_info->count) {
                        ping_finalize(ping_info);
                        raw_remove(pcb);
                        state = INIT;
                        return CMD_DONE;
                }


                if (timer_get_ms() < ping_info->last_rx_tm + ping_info->interval) {
                        return CMD_INPROGRESS;
                }
                ping_send(pcb, ping_info);

                state = WAIT_REPLY;
                return CMD_INPROGRESS;

        case WAIT_REPLY:
                if (ping_info->flags & PING_REPLY) {
                        ping_info->flags &= (~PING_REPLY);
                        state = PING;
                        return CMD_INPROGRESS;
                }

                if (timer_get_ms() >
                    ping_info->last_tx_tm + ping_info->timeout) {
                        if (!ping_info->quiet)
                                printk("timeout from %s\n",
                                       ip2str(ping_info->destination));
                        state = PING;
                        return CMD_INPROGRESS;
                }

                if (ping_info->deadline &&
                    timer_get_ms() >
                    ping_info->first_tx_tm + ping_info->deadline * 1000) {
                        ping_finalize(ping_info);
                        raw_remove(pcb);
                        state = INIT;
                        return CMD_DONE;
                }

                return CMD_INPROGRESS;
        }

        /* unreachable */
        assert(0);
	return CMD_DONE;
}