static err_t tcp_accept_callback(void *arg, struct tcp_pcb *newpcb, err_t err) { struct socket * sock = (struct socket *) arg; debug_tcp_print("socket num %ld", get_sock_num(sock)); assert(err == ERR_OK && newpcb); assert(sock->flags & SOCK_FLG_OP_LISTENING); if (sock->flags & SOCK_FLG_OP_PENDING) { int ret; ret = tcp_do_accept(sock, &sock->mess, newpcb); sock_revive(sock, ret); sock->flags &= ~SOCK_FLG_OP_PENDING; if (ret == OK) { return ERR_OK; } /* in case of an error fall through */ } /* If we cannot accept rightaway we enqueue the connection for later */ debug_tcp_print("Enqueue connection sock %ld pcb %p\n", get_sock_num(sock), newpcb); if (sock_enqueue_data(sock, newpcb, 1) != OK) { tcp_abort(newpcb); return ERR_ABRT; } if (sock_select_read_set(sock)) sock_select_notify(sock); return ERR_OK; }
static void udp_recv_callback(void *arg, struct udp_pcb *pcb, struct pbuf *pbuf, ip_addr_t *addr, u16_t port) { struct socket * sock = (struct socket *) arg; struct udp_recv_data * data; debug_udp_print("socket num : %ld addr : %x port : %d\n", get_sock_num(sock), (unsigned int) addr->addr, port); if (sock->flags & SOCK_FLG_OP_PENDING) { /* we are resuming a suspended operation */ int ret; ret = udp_do_receive(sock, &sock->req, pcb, pbuf, addr, port); send_req_reply(&sock->req, ret); sock->flags &= ~SOCK_FLG_OP_PENDING; if (ret > 0) { pbuf_free(pbuf); return; } } /* Do not enqueue more data than allowed */ if (sock->recv_data_size > UDP_BUF_SIZE) { pbuf_free(pbuf); return; } /* * nobody is waiting for the data or an error occured above, we enqueue * the packet */ if (!(data = udp_recv_alloc())) { pbuf_free(pbuf); return; } data->ip = *addr; data->port = port; data->pbuf = pbuf; if (sock_enqueue_data(sock, data, data->pbuf->tot_len) != OK) { udp_recv_free(data); return; } /* * We don't need to notify when somebody is already waiting, reviving * read operation will do the trick for us. But we must announce new * data available here. */ if (sock_select_read_set(sock)) sock_select_notify(sock); }
int raw_socket_input(struct pbuf * pbuf, struct nic * nic) { struct socket * sock; struct pbuf * pbuf_new; if ((sock = nic->raw_socket) == NULL) return 0; debug_print("socket num : %ld", get_sock_num(sock)); if (sock->flags & SOCK_FLG_OP_PENDING) { int ret; /* we are resuming a suspended operation */ ret = raw_receive(&sock->mess, pbuf); if (ret > 0) { sock_reply(sock, ret); sock->flags &= ~SOCK_FLG_OP_PENDING; return 0; } else { sock_reply(sock, ret); sock->flags &= ~SOCK_FLG_OP_PENDING; } } /* Do not enqueue more data than allowed */ if (sock->recv_data_size > RAW_BUF_SIZE) { return 0; } /* * nobody is waiting for the data or an error occured above, we enqueue * the packet. We store a copy of this packet */ pbuf_new = pbuf_alloc(PBUF_RAW, pbuf->tot_len, PBUF_RAM); if (pbuf_new == NULL) { debug_print("LWIP : cannot allocated new pbuf\n"); return 0; } if (pbuf_copy(pbuf_new, pbuf) != ERR_OK) { debug_print("LWIP : cannot copy pbuf\n"); return 0; } /* * If we didn't managed to enqueue the packet we report it as not * consumed */ if (sock_enqueue_data(sock, pbuf_new, pbuf_new->tot_len) != OK) { pbuf_free(pbuf_new); } return 0; }
static int enqueue_rcv_data(struct socket * sock, struct pbuf * pbuf) { /* Do not enqueue more data than allowed */ if (0 && sock->recv_data_size > 4 * TCP_BUF_SIZE) return ERR_MEM; if (sock_enqueue_data(sock, pbuf, pbuf->tot_len) != OK) { debug_tcp_print("data enqueueing failed"); return ERR_MEM; } debug_tcp_print("enqueued %d bytes", pbuf->tot_len); //printf("enqueued %d bytes, queue %d\n", pbuf->tot_len, sock->recv_data_size); return ERR_OK; }
static u8_t raw_ip_op_receive(void *arg, __unused struct raw_pcb *pcb, struct pbuf *pbuf, ip_addr_t *addr) { struct socket * sock = (struct socket *) arg; struct raw_ip_recv_data * data; int ret; debug_print("socket num : %ld addr : %x\n", get_sock_num(sock), (unsigned int) addr->addr); if (sock->flags & SOCK_FLG_OP_PENDING) { /* we are resuming a suspended operation */ ret = raw_ip_do_receive(&sock->mess, pbuf); if (ret > 0) { sock_reply(sock, ret); sock->flags &= ~SOCK_FLG_OP_PENDING; if (sock->usr_flags & NWIO_EXCL) { pbuf_free(pbuf); return 1; } else return 0; } else { sock_reply(sock, ret); sock->flags &= ~SOCK_FLG_OP_PENDING; } } /* Do not enqueue more data than allowed */ if (sock->recv_data_size > RAW_IP_BUF_SIZE) return 0; /* * nobody is waiting for the data or an error occured above, we enqueue * the packet */ if (!(data = raw_ip_recv_alloc())) { return 0; } data->ip = *addr; if (sock->usr_flags & NWIO_EXCL) { data->pbuf = pbuf; ret = 1; } else { /* we store a copy of this packet */ data->pbuf = pbuf_alloc(PBUF_RAW, pbuf->tot_len, PBUF_RAM); if (data->pbuf == NULL) { debug_print("LWIP : cannot allocated new pbuf\n"); raw_ip_recv_free(data); return 0; } if (pbuf_copy(data->pbuf, pbuf) != ERR_OK) { debug_print("LWIP : cannot copy pbuf\n"); raw_ip_recv_free(data); return 0; } ret = 0; } /* * If we didn't managed to enqueue the packet we report it as not * consumed */ if (sock_enqueue_data(sock, data, data->pbuf->tot_len) != OK) { raw_ip_recv_free(data); ret = 0; } return ret; }