CSE477 / swimate_v2

Dependencies:   Adafruit_GFX_128x64 DS3231 PinDetect SDFileSystem USBDevice mbed RealtimeMath MODSERIAL

Revision:
18:06b718f8e6fd
Parent:
14:006d9087d76c
Child:
22:9350752f5414
--- a/sync.cpp	Wed May 28 23:15:05 2014 +0000
+++ b/sync.cpp	Thu Jun 05 19:09:07 2014 +0000
@@ -3,141 +3,251 @@
 #include "DS3231.h"
 #include "Timeout.h"
 #include "SDFileSystem.h"
+#include "MODSERIAL.h"
+#include "debug.h"
+#include <string>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <limits.h>
+#include <time.h>
+#include "comms.h"
+
 enum state {IDLE, CAPTURE, SYNC};
 extern enum state State;
 extern DS3231 rtc;
 Timeout t;
 
-char buff[513];
-/*
-    PACKET STRUCTURE:
-    
-    Command:
-        [ 1 CMD | 17 SESSION_ID (optional) ]
-    
-    Response:
-        [ 1 ACK/NACK | X Data (optional) ]
-        
-    Byte | Description
-    ------------------
-    0x1  | ACK        
-    0x0  | NACK         
-    0x2  | Delete All  
-    0x4  | Receive file 
-*/
-
-RawSerial bt(P0_19, P0_18); // tx, rx
-
+//MODSERIAL bt(P0_19, P0_18); // tx, rx
+Comms btComm;
 uint16_t packetSeq = 0;
 
-bool sync_init() {
-    bt.baud(115200);
+bool sync_init()
+{
     return true;
 }
 
 
-struct responsePacket {
-    char cmd;
-    uint16_t len;
-    char data;
-};
+
+//void setRtc(packet *p)
+//{
+//    int dayOfWeek=0, date, month, year, hours, minutes, seconds;
+//    uint16_t len;
+//    len = getLen();
+//    int i = 0;
+//    for(i = 0; i < len; i++)
+//    {
+//        buff[i] = bt.getc();
+//    }
+//    buff[i] = 0; // end the string with a zero
+//    sscanf(buff, "%04d-%02d-%02d %02d:%02d:%02d",&year,&month,&date,&hours,&minutes,&seconds);
+//    rtc.setDate(dayOfWeek, date, month, year);
+//    rtc.setTime(hours, minutes, seconds);
+//    //sendResponse(CMD_RTCSET, ACK);
+//}
 
-void sendResponse(char cmd, char resp)
+//void listSessions()
+//{   //todo buffer this with buff
+//    DIR *dp;
+//    struct dirent *dirp;
+//    dp = opendir("/sd/");
+//    while((dirp = readdir(dp)) != NULL) {
+//        bt.puts(dirp->d_name);
+//        bt.putc(',');
+//        //todo: put size here?
+//        bt.puts("\r\\n");
+//    }
+//    closedir(dp);
+//}
+
+//void syncSession()
+//{
+//    //sendResponse(buf[0], resp);
+//    //populate packet:
+//    //1 byte CMD_SYNCSESSION 0x03
+//    //2 bytes packet number
+//    //2 bytes current packet's data's length
+//    //2 bytes checksum
+//}
+//
+
+/* Sends a file over BT stream.  Returns
+ * true on success, false on failure. */
+bool sendFile(string filename)
 {
+    PC_PRINTLNF("sendFile: Trying to open file %s", filename.c_str());
+    FILE *fp = fopen(filename.c_str(), "r");
+    if (fp == NULL) {
+        PC_PRINTLNF("sendFile: Error opening file %s", filename.c_str());
+        return false;
+    }
+
+    uint8_t *d = new uint8_t[PACKET_MAX_DATA];
     
-    struct responsePacket rp = {
-        cmd,
-        4,
-        resp};
+    PC_PRINTLN("sendFile: created buffer");
+    int len;
+    while ( (len = fread(d, 1, PACKET_MAX_DATA, fp) ) > 0 ) {
+        PC_PRINTLNF("sendFile: sending packet of length %d", len);
+
+        Packet *p = Packet::create(CMD_SYNCOLDEST, 0x00, len, d);
+        btComm.sendPacket(p);
+        delete p;
         
-    bt.puts((char*)&rp);
+        PC_PRINTLNF("sendFile: sent packet of length %d", len);
+    }
+    delete[] d;
+
+    PC_PRINTLNF("sendFile: done sending %s", filename.c_str());
+    // Appears to be a bug where feof isn't defined, so no error checking :(
+//    if (!feof(fp)) {
+//        PC_PRINTLNF("sendFile: Error reading file %s", absolute_filename.c_str());
+//        return false;
+//    }
+
+    Packet *p = Packet::create(CMD_SYNCOLDEST, 0x00, 0x00, 0x00);
+    btComm.sendPacket(p);
+    delete p;
+    
+    fclose(fp);
+    return true;
 }
 
-
-uint16_t getLen()
-{
-    union Lu
-    {
-        int16_t len;
-        char dat[2];
-    };
-    union Lu lu;
-    lu.dat[0] = bt.getc();
-    lu.dat[1] = bt.getc();
-    
-    return lu.len;
-}
-
-void setRtc()
+/* Returns absolute filename of the oldest log file on the SD card */
+bool getOldestFile(string *oldest) 
 {
-    int dayOfWeek=0, date, month, year, hours, minutes, seconds;
-    int16_t len;
-    len = getLen();
-    int i = 0;
-    for(i = 0; i < len; i++)
-    {
-        buff[i] = bt.getc();
-    }
-    buff[i] = 0; // end the string with a zero
-    sscanf(buff, "%04d-%02d-%02d %02d:%02d:%02d",&year,&month,&date,&hours,&minutes,&seconds);
-    rtc.setDate(dayOfWeek, date, month, year);
-    rtc.setTime(hours, minutes, seconds);
-    sendResponse(CMD_RTCSET, ACK);
+    
+    PC_PRINTLN("Finding oldest file...");
     
-}
-void listSessions()
-{   //todo buffer this with buff
+    // Ensure all fields get set to zero
+    long long file_time = {0};
+    long long oldest_time = LLONG_MAX;  // ensures first file gets set to oldest
+    string oldest_file;
+
     DIR *dp;
     struct dirent *dirp;
     dp = opendir("/sd/");
-    while((dirp = readdir(dp)) != NULL) {
-        bt.puts(dirp->d_name);
-        bt.putc(',');
-        //todo: put size here?
-        bt.puts("\r\\n");
-    }
-    closedir(dp);
-}
 
-void syncSession()
-{
-    
-    
-}
+    if (dp == NULL) {
+      PC_PRINTLN("syncOldestSession: Error opening directory");
+      return false;
+    }
 
-void deleteSession()
-{
-    
-    
-}
+    while((dirp = readdir(dp)) != NULL) {
+        char *strp = dirp->d_name;
 
-void sync() {
-    while(State == SYNC)
-    {
-        if(bt.readable()) // get the latest byte available
-        {
-            buff[0] = bt.getc();
-            
-            switch(buff[0])
-            {
-                case CMD_RTCSET:
-                    setRtc();
-                    break;
-                case CMD_LISTSESSIONS:
-                    listSessions();
-                    break;
-                case CMD_SYNCSESSION:
-                    syncSession();
-                    break;
-                case CMD_DELETESESSION:
-                    deleteSession();
-                    break;
-                case CMD_DONE:
-                    bt.putc(CMD_DONE);
-                    sendResponse(CMD_DONE, ACK);
-                    State = IDLE;
-                    break;
+        // Verify we are looking at a .log file
+        char ext[5];
+        memcpy(ext, strp+strlen(strp) - 4, 5);
+        if (strncmp(ext, ".log", 4) == 0) {
+            PC_PRINTLNF("syncOldestSession: reading file %s", dirp->d_name);
+
+            file_time = strtoll(strp, NULL, 10);
+
+            // If file time is older than oldest time, set the oldest file
+            //   to the current file
+            if (file_time < oldest_time) {
+                PC_PRINTLN("syncOldestSession: updating oldest file");
+                oldest_time = file_time;
+                oldest_file = strp;
             }
         }
     }
+    
+    PC_PRINTLNF("getOldestFile: prepending /sd/ to %s", oldest_file.c_str());
+    *oldest = "/sd/";
+    *oldest += oldest_file;
+    
+    closedir(dp);
+    return true;    
+}
+
+bool syncOldestSession()
+{
+    string oldest;
+    
+    if (getOldestFile(&oldest))
+        return sendFile(oldest);
+    
+    return false;
+}
+
+bool deleteOldestSession()
+{
+    string oldest;
+    
+    if (getOldestFile(&oldest)) {
+        PC_PRINTLNF("deleteOldestSession: deleting %s", oldest.c_str());
+        
+        if (remove(oldest.c_str()) == 0) {
+           PC_PRINTLN("deleteOldestSession: delete success");
+           // send ack
+           return true;
+        }
+    }
+        
+    // send ack
+        
+    return false;
+}
+
+void sync()
+{
+    PC_PRINTLN("Entered sync mode...");
+    while(State == SYNC) {
+        PC_PRINTLN("Waiting for packet...")
+        Packet *p; 
+        int ret = btComm.receivePacket(&p, 1000);
+        if (ret == 0) {
+            PC_PRINTLN("Timeout!");
+            continue;
+        } else if (ret < 0) {
+            PC_PRINTLN("Received bad packet :(");
+            continue;
+        }
+
+        PC_PRINTLNF("cmd: %x", p->cmd);
+        PC_PRINTLNF("pnum: %x", p->packetNumber);
+        PC_PRINTLNF("len: %x", p->dataLength);
+        for (int i = 0; i < p->dataLength; i++) {
+            PC_PRINTF("data[%d]: ", i);
+            PC_PRINTLNF("%x", p->data[i]);
+        }
+        PC_PRINTLNF("check: %x", p->checkSum);
+        
+        btComm.sendPacket(p);
+        
+        PC_PRINTLN("Echoed packet");
+        switch(p->cmd) {
+            case CMD_SYNCOLDEST:
+                if (!syncOldestSession())
+                    PC_PRINTLN("Sync oldest session failed!");
+                    break;
+            case CMD_DELETEOLDEST:
+                if (!deleteOldestSession())
+                    PC_PRINTLN("Delete oldest session failed!");
+                    break;
+//                case CMD_RTCSET:
+//                    //setRtc(p);
+//                    break;
+//                case CMD_LISTSESSIONS:
+//                    listSessions();
+//                    break;
+//                case CMD_SYNCSESSION:
+//                    syncSession();
+//                    break;
+//                case CMD_DELETESESSION:
+//                    deleteSession();
+//                    break;
+//                case CMD_DONE:
+//                    bt.putc(CMD_DONE);
+//                    //sendResponse(CMD_DONE, ACK);
+//                    State = IDLE;
+//                    break;
+//                default: break;
+        }
+
+        PC_PRINTLN("Deleting received packet...");
+        delete p;
+        PC_PRINTLN("Ready for new packet");
+    }
 }
\ No newline at end of file