+/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
+/* (c) 2008, Lei Xia <xiaxlei@gmail.com> */
+/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+
#include <geekos/socket.h>
#include <geekos/malloc.h>
#include <geekos/ne2k.h>
#include <uip/uip_arp.h>
#include <geekos/vmm_stubs.h>
#include <geekos/debug.h>
-
+#include <geekos/timer.h>
#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
struct socket sockets[MAX_SOCKS];
+void socket_appcall(void);
+#ifndef UIP_APPCALL
+#define UIP_APPCALL socket_appcall
+#endif /* UIP_APPCALL */
+
-int Packet_Received(struct NE2K_Packet_Info* info, uchar_t *pkt);
-void init_network() {
+static int Packet_Received(struct NE2K_Packet_Info* info, uchar_t *pkt);
+static void periodic_caller(int timer_id, void * arg);
+
+void init_socket_layer() {
int i = 0;
+ bool iflag;
+
for (i = 0; i < MAX_SOCKS; i++) {
sockets[i].in_use = 0;
}
+
//initiate uIP
uip_init();
uip_arp_init();
//setup device driver
Init_Ne2k(&Packet_Received);
-
+ iflag = Begin_Int_Atomic();
+ Start_Timer(2, periodic_caller, NULL);
+ End_Int_Atomic(iflag);
}
}
+
+static void periodic_caller(int timer_id, void * arg) {
+ int i;
+ //handle the periodic calls of uIP
+
+ //PrintBoth("Timer CALLBACK handler\n");
+
+ for(i = 0; i < UIP_CONNS; ++i) {
+ uip_periodic(i);
+ if(uip_len > 0) {
+ //devicedriver_send();
+ PrintBoth("Sending Packet\n");
+ NE2K_Transmit(uip_len);
+ }
+ }
+ for(i = 0; i < UIP_UDP_CONNS; i++) {
+ uip_udp_periodic(i);
+ if(uip_len > 0) {
+ //devicedriver_send();
+ NE2K_Transmit(uip_len);
+ }
+ }
+}
+
+
int connect(const uchar_t ip_addr[4], ushort_t port) {
int sockfd = -1;
sockfd = allocate_socket_fd();
- uip_ipaddr_t ipaddr;
+ static uip_ipaddr_t ipaddr;
if (sockfd == -1) {
return -1;
}
uip_ipaddr(&ipaddr, ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3]);
-
- sockets[sockfd].state = WAITING;
- sockets[sockfd].con = uip_connect((uip_ipaddr_t *)&ip_addr, htons(port));
+ sockets[sockfd].con = uip_connect(&ipaddr, htons(port));
if (sockets[sockfd].con == NULL){
PrintBoth("Connection start\n");
-
- while(sockets[sockfd].state == WAITING) {
- timer_int_handler(NULL);
- }
-
+ Wait(&(sockets[sockfd].recv_wait_queue));
+
PrintBoth("Connected\n");
- if (sockets[sockfd].state != ESTABLISHED) {
- release_socket_fd(sockfd);
- return -1;
- }
+
return sockfd;
return recvlen;
}
-void timer_int_Handler(struct Interrupt_State * state){
- int i;
- //handle the periodic calls of uIP
- for(i = 0; i < UIP_CONNS; ++i) {
- uip_periodic(i);
- if(uip_len > 0) {
- //devicedriver_send();
- NE2K_Transmit(uip_len);
- }
- }
- for(i = 0; i < UIP_UDP_CONNS; i++) {
- uip_udp_periodic(i);
- if(uip_len > 0) {
- //devicedriver_send();
- NE2K_Transmit(uip_len);
- }
- }
-}
+
// a series of utilities to handle conncetion states
static void connected(int sockfd) {
-int Packet_Received(struct NE2K_Packet_Info * info, uchar_t * pkt) {
+static int Packet_Received(struct NE2K_Packet_Info * info, uchar_t * pkt) {
//int i;
-
uip_len = info->size;
// for (i = 0; i < info->size; i++) {
// uip_buf[i] = *(pkt + i);
//}
+ PrintBoth("Packet REceived\n");
+
memcpy(uip_buf, pkt, uip_len);
Free(pkt);
if (BUF->type == htons(UIP_ETHTYPE_ARP)) {
+ PrintBoth("ARP PACKET\n");
+
uip_arp_arpin();
+
if (uip_len > 0) {
+ PrintBoth("Transmitting\n");
NE2K_Transmit(uip_len);
- }
+ }
+
} else {
-
+ PrintBoth("Data PACKET\n");
uip_arp_ipin();
uip_input();
+
if (uip_len > 0) {
+ PrintBoth("Transmitting\n");
uip_arp_out();
NE2K_Transmit(uip_len);
}
+
}
-
- return 0;
+ return 0;
}