1 /* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
2 /* (c) 2008, Lei Xia <xiaxlei@gmail.com> */
3 /* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
5 #include <geekos/socket.h>
6 #include <geekos/malloc.h>
7 #include <geekos/ne2k.h>
9 #include <uip/uip_arp.h>
10 #include <geekos/vmm_stubs.h>
11 #include <geekos/debug.h>
12 #include <geekos/timer.h>
15 #define BUF ((struct uip_eth_hdr *)&uip_buf[0])
17 #define MAX_SOCKS 1024
20 struct socket sockets[MAX_SOCKS];
22 void socket_appcall(void);
24 #define UIP_APPCALL socket_appcall
25 #endif /* UIP_APPCALL */
30 static int Packet_Received(struct NE2K_Packet_Info* info, uchar_t *pkt);
31 static void periodic_caller(int timer_id, void * arg);
33 void init_socket_layer() {
38 for (i = 0; i < MAX_SOCKS; i++) {
39 sockets[i].in_use = 0;
40 sockets[i].send_buf = NULL;
41 sockets[i].recv_buf = NULL;
42 sockets[i].state = CLOSED;
52 Init_Ne2k(&Packet_Received);
54 iflag = Begin_Int_Atomic();
55 Start_Timer(2, periodic_caller, NULL);
56 End_Int_Atomic(iflag);
63 void set_ip_addr(uchar_t addr[4]) {
65 uip_ipaddr(ipaddr, addr[0], addr[1], addr[2], addr[3]); /* Local IP address */
66 uip_sethostaddr(ipaddr);
70 static int allocate_socket_fd() {
73 for (i = 0; i < MAX_SOCKS; i++) {
74 if (sockets[i].in_use == 0) {
75 sockets[i].in_use = 1;
76 sockets[i].send_buf = create_ring_buffer(BUF_SIZE);
77 if (sockets[i].send_buf == NULL)
79 sockets[i].recv_buf = create_ring_buffer(BUF_SIZE);
80 if (sockets[i].recv_buf == NULL){
81 free_ring_buffer(sockets[i].send_buf);
91 static int release_socket_fd(int sockfd){
92 if (sockfd >= 0 && sockfd < MAX_SOCKS){
93 sockets[sockfd].in_use = 0;
94 free_ring_buffer(sockets[sockfd].send_buf);
95 free_ring_buffer(sockets[sockfd].recv_buf);
96 sockets[sockfd].send_buf = NULL;
97 sockets[sockfd].recv_buf = NULL;
98 sockets[sockfd].state = CLOSED;
105 struct socket * get_socket_from_fd(int fd) {
106 return &(sockets[fd]);
111 static void periodic_caller(int timer_id, void * arg) {
113 //handle the periodic calls of uIP
115 //PrintBoth("Timer CALLBACK handler\n");
117 for(i = 0; i < UIP_CONNS; ++i) {
120 //devicedriver_send();
121 PrintBoth("Sending Packet\n");
122 NE2K_Transmit(uip_len);
125 for(i = 0; i < UIP_UDP_CONNS; i++) {
128 //devicedriver_send();
129 NE2K_Transmit(uip_len);
135 int connect(const uchar_t ip_addr[4], ushort_t port) {
137 sockfd = allocate_socket_fd();
138 static uip_ipaddr_t ipaddr;
144 uip_ipaddr(&ipaddr, ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3]);
146 sockets[sockfd].con = uip_connect(&ipaddr, htons(port));
149 if (sockets[sockfd].con == NULL){
150 release_socket_fd(sockfd);
155 PrintBoth("Connection start\n");
156 Wait(&(sockets[sockfd].recv_wait_queue));
159 PrintBoth("Connected\n");
167 int recv(int sockfd, void * buf, uint_t len){
170 struct socket *sock = get_socket_from_fd(sockfd);
173 // here we need some lock mechnism, just disable interrupt may not work properly because recv() will be run as a kernel thread
175 recvlen = rb_read(sock->recv_buf, buf, len);
178 Wait(&(sock->recv_wait_queue));
187 // a series of utilities to handle conncetion states
188 static void connected(int sockfd) {
189 struct socket * sock = get_socket_from_fd(sockfd);
191 PrintBoth("Connected Interrupt\n");
193 sock->state = ESTABLISHED;
195 Wake_Up(&(sock->recv_wait_queue));
198 static void closed(int sockfd){
202 static void acked(int sockfd){
206 static void newdata(int sockfd){
213 dataptr = (char *)uip_appdata;
218 sock = get_socket_from_fd(sockfd);
220 wrlen = rb_write(sock->recv_buf, dataptr, len);
222 if (wrlen < len){ //write error, what should I do?
226 Wake_Up(&(sock->recv_wait_queue));
233 static void send_to_driver(int sockfd) {
235 PrintBoth("Sending data to driver\n");
241 int send(int sockfd, void * buf, uint_t len) {
242 struct socket * sock = get_socket_from_fd(sockfd);
243 //int mss = uip_mss();
244 //int pending_bytes = rb_data_len(sock->send_buf);
245 //int len = (mss < pending_bytes) ? mss: pending_bytes;
247 uchar_t * send_buf = uip_appdata;
249 bytes_read = rb_peek(sock->send_buf, send_buf, len);
251 if (bytes_read == 0) {
252 // no packet for send
256 uip_send(send_buf, len);
263 //get the socket id by the local tcp port
264 static int get_socket_from_port(ushort_t lport) {
268 for (i = 0; i < MAX_SOCKS; i++){
269 if (sockets[i].con->lport == lport) {
279 void socket_appcall(void) {
283 sockfd = get_socket_from_port(uip_conn->lport);
285 PrintBoth("Appcall\n");
292 if (uip_connected()) {
297 if (uip_closed() ||uip_aborted() ||uip_timedout()) {
315 send_to_driver(sockfd);
322 static int Packet_Received(struct NE2K_Packet_Info * info, uchar_t * pkt) {
324 uip_len = info->size;
326 // for (i = 0; i < info->size; i++) {
327 // uip_buf[i] = *(pkt + i);
330 PrintBoth("Packet REceived\n");
332 memcpy(uip_buf, pkt, uip_len);
337 if (BUF->type == htons(UIP_ETHTYPE_ARP)) {
338 PrintBoth("ARP PACKET\n");
344 PrintBoth("Transmitting\n");
345 NE2K_Transmit(uip_len);
350 PrintBoth("Data PACKET\n");
356 PrintBoth("Transmitting\n");
358 NE2K_Transmit(uip_len);