//  firmware to receive bytes from atmega186 over USART and send over Wifi
//  The atmega168 is programmed to talk to the pn532 nfc card reader and then send the card info
//    over USART.

#define debug 0
#define MAXLEN 256

TCPServer server = TCPServer(2342);
TCPClient client;
bool unlocked = false;

void setup() {
    
    Serial1.begin(9600);
    Serial1.setTimeout(0);
    if (debug) {
        Serial.begin(9600);
        while(!Serial.available()) SPARK_WLAN_Loop();
    
        Serial.println("Listening for connection...");
        if (WiFi.ready()) {
            Serial.println(WiFi.localIP());
        } else {
            Serial.println("wifi not ready");
        }
    }
    
    server.begin();
    Serial1.flush();
    
}


int pollSerial() {
    bool on = false;
    bool found = false;
    if (debug) {
        Serial.println("connected");
    }
    
    client.setTimeout(0);
    int i, success;
    unsigned long scantime;
    char cmd, valL, valH;
    //char *rec_buf;
    uint8_t dataframe[32];
    int intvalL, intvalH;
    
    client.flush();
    
    while (true) {
        
        char s_buff[MAXLEN] = {0};
        
        
        if (on) {
            Serial1.flush();
            scantime = 0;      // use for timeout
            while (scantime++ < 10000000) {
                if (Serial1.available()) {
                    Serial1.readBytes(s_buff, 64);
                    if (debug) {
                        for (i=0;i<32;i++) {
                        Serial.print(s_buff[i]);
                        }
                    }
                    
                    if (s_buff[0] == 2) {
                        break;
                    }
                }
                
            }
            if (scantime >= 10000000) {
                dataframe[0] = 0x82;
                dataframe[1] = 0xF2;
                dataframe[2] = 0xFF;
                success = server.write((uint8_t *)dataframe, 3);
                on = false;
                continue;
            }
            
            dataframe[0] = 0x81;
            for (i = 1;i < 15;i++) {
                dataframe[i] = s_buff[i];
            }
            dataframe[i] = '\0';
            
            success = server.write((uint8_t *)dataframe, 16);
            
            if (!success) {
                    Serial.println("dataframe name failed");
            }
            
            cmd = 0xA1;
            valL = ((s_buff[19] - 0x30) * 10) + (s_buff[20] - 0x30);
            valH = ((s_buff[21] - 0x30) * 10) + (s_buff[22] - 0x30);
            Serial.println(valL);
            Serial.println(valH);
            
            dataframe[0] = 0x82;
            dataframe[1] = cmd;
            dataframe[2] = valL;
            dataframe[3] = valH;
            
            success = server.write(dataframe, 4);
            if (debug) {
                for (i=0;i<5;i++) {
                    Serial.print(dataframe[i]);
                }
                if (!success)
                    Serial.println("dataframe value failed");
            }
            on = false;
        }
        /* check for incomming */
        char rec_buf[MAXLEN] = {0};
        if (client.available()) {
            if (debug) {
                Serial.println("data to recieve");
            }
            
            char count[1];
            int  bytes;
    
            bytes = client.readBytes(count, 1);      //returns ascii rep of value
            if (bytes < 0) {
                rec_buf[0] = '\0';
            }                           
            bytes = client.readBytes((char *)rec_buf, count[0]);  
   
            rec_buf[count[0]] = '\0';
            
            if (unlocked) {
                /*first byte: opcode
                 *seconde byte: cmd
                 *3-paylen bytes: data
                 */
                 if (debug) {
                     for (i = 0;i < 16;i++) {
                         Serial.print(rec_buf[i]);
                     }
                 }
                 if (rec_buf[2] == 0x80) {
                     if (debug) {
                         Serial.println("Bye!");
                     }
                     
                     cmd = 0xF1;
                     valL = 0xFF;
                     valH = 0xFF;
                     dataframe[0] = 0x82;
                     dataframe[1] = cmd;
                     dataframe[2] = valL;
                     dataframe[3] = valH;
                     success = server.write(dataframe, 4);
                     if (!success) {
                         if (debug) {
                             Serial.println("couldn't send no pass");
                         }
                        client.stop();
                        break;
                     }
                 }
                 if (rec_buf[2] == 0x20) {
                     on = true;
                     if (debug) {
                         Serial.println("scanning..");
                     }
                     
                 }
        
            } 
        }
    }
    
    return 0;
}

int verifyPass() {
    char rec_buf[MAXLEN] = {0};
    char count[1];
    int  bytes;
    
    bytes = client.readBytes(count, 1);      //returns ascii rep of value
    if (bytes < 0) {
        rec_buf[0] = '\0';
    }                           
    bytes = client.readBytes((char *)rec_buf, count[0]);  
   
    rec_buf[count[0]] = '\0';
    
    if (strcmp((char *)rec_buf, "yousuck") != 0) {
        if (debug) {
            Serial.println("incorrect password");
        Serial.println(rec_buf);
        }
        return 0;
    }
    unlocked = true;
    return 1;
}

void loop() {
    
    if (client.connected()) {
        client.flush();
        if (!verifyPass()) {
            if (debug) 
                Serial.println("exiting");
            
            client.stop();
            while (true) {};
        }
        pollSerial();
    } else {
        client = server.available();
    }
}