/*
* Socket App
*
* A simple socket application example using the WiShield 1.0
*/

#include <WiShield.h>
//#include <string.h>
extern "C" {   
  #include <uip.h>
}

//Wireless configuration defines ----------------------------------------
#define WIRELESS_MODE_INFRA   1
#define WIRELESS_MODE_ADHOC   2

//Wireless configuration parameters ----------------------------------------

unsigned char local_ip[] = {192,168,22,202};   // IP address of WiShield
unsigned char gateway_ip[] = {192,168,22,1};   // router or gateway IP address
unsigned char subnet_mask[] = {255,255,255,0};   // subnet mask for the local network
const prog_char ssid[] PROGMEM = {"**********"};      // max 32 bytes
unsigned char security_type = 3;   // 0 - open; 1 - WEP; 2 - WPA; 3 - WPA2
// WPA/WPA2 passphrase
const prog_char security_passphrase[] PROGMEM = {"**********"};   // max 64 characters
// WEP 128-bit keys
prog_uchar wep_keys[] PROGMEM = {
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Key 0
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Key 1
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Key 2
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // Key 3
// setup the wireless mode
// infrastructure - connect to AP
// adhoc - connect to another WiFi device
unsigned char wireless_mode = WIRELESS_MODE_INFRA;
unsigned char ssid_len;
unsigned char security_passphrase_len;

// End of wireless configuration parameters ----------------------------------------

boolean connectToServer(void);

boolean connectedToServer = false;
boolean inited = false;   
unsigned long   nextXMitTime;

void setup() {
  Serial.begin(57600);   
  Serial.println("Starting Program..."); 
  connectedToServer = false; 
  WiFi.init();   
}

void loop() {
  WiFi.run();

  if (millis() > nextXMitTime && inited && !connectedToServer) {
    Serial.print("Connecting to server...");
    if (connectToServer()) {
      connectedToServer = true;
      Serial.println("connection OK");
    } else {
      Serial.println("connection NOT OK");
    }
  }
}

// Make connection to 192.168.22.101:2323
boolean connectToServer(void) {   
  struct uip_conn *conn;
  uip_ipaddr_t ipaddr;

  uip_ipaddr(&ipaddr, 192,168,22,101);
  conn = uip_connect(&ipaddr, HTONS(2323));

  return (conn != NULL);
}

extern "C" {

  void socket_app_init() {
    Serial.println("In socket_app_init...");
    inited = true;
    nextXMitTime = millis();
  }

  void socket_app_appcall() {
    Serial.println("In socket_app_appcall...");
    if (uip_connected()) {
      Serial.println("{connected}");
      uip_send("Hello!...\r\n", 11);   
    }   

    if (uip_aborted()) {
      Serial.println("{aborted}");
      connectedToServer = false;
    }

    if (uip_timedout()) {
      Serial.println("{timedout}");
      connectedToServer = false;
    }   

    if(uip_closed() && !uip_newdata()) {
      Serial.println("{closed}");
      if (connectedToServer) {
        nextXMitTime += 30000L;// XMit again in 30 seconds
        connectedToServer = false;
      }
    }   

    if (uip_rexmit()) {
      Serial.println("{retransmit}");
      uip_send("Hello...\r\n", 10);   
    }   

    if (uip_acked()) { 
    }

    if(uip_newdata()) { 
      unsigned int len = uip_datalen();
      Serial.write((const uint8_t*)uip_appdata, len);
    }
  }
}