struct uip_conn *uip_tcpaccept(struct uip_tcpip_hdr *buf) { struct uip_conn *conn = uip_tcpalloc(); if (conn) { /* Fill in the necessary fields for the new connection. */ conn->rto = UIP_RTO; conn->timer = UIP_RTO; conn->sa = 0; conn->sv = 4; conn->nrtx = 0; conn->lport = buf->destport; conn->rport = buf->srcport; conn->mss = UIP_TCP_INITIAL_MSS; uip_ipaddr_copy(conn->ripaddr, uip_ip4addr_conv(buf->srcipaddr)); conn->tcpstateflags = UIP_SYN_RCVD; uip_tcpinitsequence(conn->sndseq); conn->unacked = 1; #ifdef CONFIG_NET_TCP_WRITE_BUFFERS conn->expired = 0; conn->isn = 0; conn->sent = 0; #endif /* rcvseq should be the seqno from the incoming packet + 1. */ memcpy(conn->rcvseq, buf->seqno, 4); #ifdef CONFIG_NET_TCP_READAHEAD /* Initialize the list of TCP read-ahead buffers */ sq_init(&conn->readahead); #endif #ifdef CONFIG_NET_TCP_WRITE_BUFFERS /* Initialize the write buffer lists */ sq_init(&conn->write_q); sq_init(&conn->unacked_q); #endif /* And, finally, put the connection structure into the active list. * Interrupts should already be disabled in this context. */ dq_addlast(&conn->node, &g_active_tcp_connections); } return conn; }
int uip_tcpconnect(struct uip_conn *conn, const struct sockaddr_in *addr) #endif { uip_lock_t flags; int port; /* The connection is expected to be in the UIP_ALLOCATED state.. i.e., * allocated via up_tcpalloc(), but not yet put into the active connections * list. */ if (!conn || conn->tcpstateflags != UIP_ALLOCATED) { return -EISCONN; } /* If the TCP port has not alread been bound to a local port, then select * one now. */ flags = uip_lock(); port = uip_selectport(ntohs(conn->lport)); uip_unlock(flags); if (port < 0) { return port; } /* Initialize and return the connection structure, bind it to the port number */ conn->tcpstateflags = UIP_SYN_SENT; uip_tcpinitsequence(conn->sndseq); conn->initialmss = conn->mss = UIP_TCP_MSS; conn->unacked = 1; /* TCP length of the SYN is one. */ conn->nrtx = 0; conn->timer = 1; /* Send the SYN next time around. */ conn->rto = UIP_RTO; conn->sa = 0; conn->sv = 16; /* Initial value of the RTT variance. */ conn->lport = htons((uint16_t)port); /* The sockaddr port is 16 bits and already in network order */ conn->rport = addr->sin_port; /* The sockaddr address is 32-bits in network order. */ uip_ipaddr_copy(conn->ripaddr, addr->sin_addr.s_addr); /* Initialize the list of TCP read-ahead buffers */ #if CONFIG_NET_NTCP_READAHEAD_BUFFERS > 0 sq_init(&conn->readahead); #endif /* And, finally, put the connection structure into the active * list. Because g_active_tcp_connections is accessed from user level and * interrupt level, code, it is necessary to keep interrupts disabled during * this operation. */ flags = uip_lock(); dq_addlast(&conn->node, &g_active_tcp_connections); uip_unlock(flags); return OK; }