int main(void) { static uint8_t buffer[BufferSize + 1]; int8_t i; uint8_t message[4] = { 0, 0, CID, P2CID }; uint16_t received; snesIO port0 = 0xffff, port1 = 0xffff; // Initialise basic I/O. initLed(); initInput(); initOutput(); // Switched mode: B + Y. port0 = recvInput(); if (port0 == 0xfffc) { switchedMode = Enabled; ledSignal(5); } ledOnRed(); // Initialise network interface. enc28j60Init(mymac); _delay_ms(100); // Magjack leds configuration, see enc28j60 datasheet, page 11 // LEDB=yellow LEDA=green // 0x476 is PHLCON LEDA=links status, LEDB=receive/transmit // enc28j60PhyWrite(PHLCON,0b0000 0100 0111 01 10); enc28j60PhyWrite(PHLCON, 0x476); _delay_ms(100); // Get the initial IP via DHCP and configure network. init_mac(mymac); while (i != 1) { received = enc28j60PacketReceive(BufferSize, buffer); buffer[BufferSize] = '\0'; i = packetloop_dhcp_initial_ip_assignment(buffer, received, mymac[5]); } dhcp_get_my_ip(myip, netmask, gwip); client_ifconfig(myip, netmask); // Resolve MAC address from server IP. if (route_via_gw(serverip)) // Must be routed via gateway. get_mac_with_arp(gwip, TransNumGwmac, &arpresolverResultCallback); else // Server is on local network. get_mac_with_arp(serverip, TransNumGwmac, &arpresolverResultCallback); while (get_mac_with_arp_wait()) { received = enc28j60PacketReceive(BufferSize, buffer); // Call packetloop to process ARP reply. packetloop_arp_icmp_tcp(buffer, received); } // Lookup DNS of the server hostname. while (dnslkup_haveanswer() != 1) { uint16_t tmp; received = enc28j60PacketReceive(BufferSize, buffer); tmp = packetloop_arp_icmp_tcp(buffer, received); if (received == 0) { if (!enc28j60linkup()) continue; dnslkup_request(buffer, ServerVHost, gwmac); _delay_ms(100); continue; } if (tmp == 0) udp_client_check_for_dns_answer(buffer, received); } dnslkup_get_ip(serverip); ledOnGreen(); // Connected. while (1) { // Main loop start. received = enc28j60PacketReceive(BufferSize, buffer); // Software reset: L + R + Select + Start. if (port0 == 0xf3f3) reset(); // Do something while no packet in queue. if (received == 0) { port0 = recvInput(); // Prepare message and send it to the server. for (i = 0; i < 8; i++) { // Lo-Byte. char *c = message; *c = port0 & (1 << i) ? *c | (1 << i) : *c & ~(1 << i); } for (i = 0; i < 8; i++) { // Hi-Byte. char *c = message + 1; *c = port0 & (1 << i + 8) ? *c | (1 << i) : *c & ~(1 << i); } send_udp(buffer, message, sizeof(message), 57351, serverip, 57350, gwmac); // Send controller data to SNES. if (switchedMode == Disabled) sendOutput(port0, port1); else sendOutput(port1, port0); continue; } // Answer to ARP requests. if (eth_type_is_arp_and_my_ip(buffer, received)) { make_arp_answer_from_request(buffer, received); continue; } // Check if IP packets (ICMP or UDP) are for us. if (eth_type_is_ip_and_my_ip(buffer, received) == 0) continue; // Answer ping with pong. if ( buffer[IP_PROTO_P] == IP_PROTO_ICMP_V && buffer[ICMP_TYPE_P] == ICMP_TYPE_ECHOREQUEST_V) { make_echo_reply_from_request(buffer, received); continue; } // Listen for UDP packets on port 57351 (0xe007) and process // received data. if ( buffer[IP_PROTO_P] == IP_PROTO_UDP_V && buffer[UDP_DST_PORT_H_P] == 0xe0 && buffer[UDP_DST_PORT_L_P] == 0x07) { for (i = 0; i < 8; i++) { uint16_t *c = &port1; *c = buffer[UDP_DATA_P] & (1 << i) ? *c | (1 << i) : *c & ~(1 << i); } for (i = 0; i < 8; i++) { uint16_t *c = &port1; *c = buffer[UDP_DATA_P + 1] & (1 << i) ? *c | (1 << i + 8) : *c & ~(1 << i + 8); } } } // Main loop end. return (0); }
/*---------------------------------------------------------------------------*/ static PT_THREAD(www_client_thread(struct pt *pt)) { PT_BEGIN(pt); while(1) { /* TODO: Add debouncing ... */ PT_WAIT_UNTIL(pt,btn2_pressed()); PT_WAIT_UNTIL(pt,!btn2_pressed()); dbg(PSTR("> Web client starts.\r\n")); retry_count = 0; do { /* disable interrupts */ cli(); /* reset timeout counter */ www_client_counter = 0; /* re-enable interrupts */ sei(); /* make a dns request */ dnslkup_request(buf,URL_base_address,gwmac); /* wait an answer ... */ PT_WAIT_UNTIL(pt,dnslkup_haveanswer()||www_client_timeout()); if(dnslkup_haveanswer()) { /* exit the loop */ retry_count = 0xFF; } else { dbg(PSTR("> DNS lookup timeout!\r\n")); retry_count++; } } while(retry_count < 5); if(dnslkup_haveanswer()) { /* save the received IP to your userspace variable */ dnslkup_get_ip(otherside_www_ip); /* reset callback state */ www_callback_state = 0; /* reset retry count */ retry_count = 0; /* browsing action */ do { /* disable interrupts */ cli(); /* reset timeout counter */ www_client_counter = 0; /* re-enable interrupts */ sei(); /* increment the trial counter */ retry_count++; client_browse_url( PSTR("/ws.php?c="), /* constant part of the URL suffix */ "Samsun", /* variable part of the URL which comes after the constant suffix */ URL_base_address, /* base-name of the web page we want to browse */ &browserresult_callback, /* callback function for our URL browsing attempt */ otherside_www_ip, /* IP representation of the webpage host */ gwmac /* mac address of our gateway */ ); /* wait ... */ PT_WAIT_UNTIL(pt,www_client_failed() || www_client_timeout() || www_client_ok() || return_counter() ); if(www_client_ok()) { /* exit the loop */ retry_count = 0xFF; } else if(www_client_failed()) { dbg(PSTR("> Browsing problem!\r\n")); } else if(www_client_timeout()) { dbg(PSTR("> Browsing timeout!\r\n")); } } while(retry_count < 5); if(retry_count == 0xFF) { dbg(PSTR("> Browsing went ok!\r\n")); } else { dbg(PSTR("> Browsing failed!\r\n")); } dbg(PSTR("> -------------------------------------\r\n")); } else { dbg(PSTR("> Browsing failed!\r\n")); dbg(PSTR("> -------------------------------------\r\n")); } } PT_END(pt); }