Swimate V2 without RTOS code

Dependencies:   Adafruit_GFX_128x64 DS3231 PinDetect SDFileSystem USBDevice mbed RealtimeMath MODSERIAL

sync.cpp.orig

Committer:
ellingjp
Date:
2014-06-09
Revision:
24:f2503d1256ad
Parent:
22:9350752f5414

File content as of revision 24:f2503d1256ad:

#include "mbed.h"
#include "sync.h"
#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 "comms.h"

enum state {IDLE, CAPTURE, SYNC};
extern enum state State;
extern DS3231 rtc;
Timeout t;

//MODSERIAL bt(P0_19, P0_18); // tx, rx
Comms btComm;
uint16_t packetSeq = 0;

bool sync_init()
{
    return true;
}



//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 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;
    }
    
    fseek(fp, 0L, SEEK_END);
    int file_size = ftell(fp);
    fseek(fp, 0L, SEEK_SET);
    
    Packet *firstPacket = Packet::create(CMD_SYNCOLDEST, 0x00, sizeof(file_size), (uint8_t *) &file_size);
    btComm.sendPacket(firstPacket);

    PC_PRINTLNF("sendFile: first packet checksum = %x", firstPacket->checkSum);
    
    delete firstPacket;
    
    Packet *res;
    int n = btComm.receivePacket(&res, TIMEOUT);
    if (n <= 0) {
        PC_PRINTLN("sendFile: timeout waiting for ack!");
        fclose(fp);
        return false;
    }

    if (res->cmd != ACK) {
        PC_PRINTLN("sendFile: packet received was not an ack!");
        delete res;
        fclose(fp);
        return false;
    }

    delete res;

    uint8_t *d = new uint8_t[PACKET_MAX_DATA];
    
    PC_PRINTLN("sendFile: created buffer");
    int len;
    int numPackets = 0;
    while ( (len = fread(d, 1, PACKET_MAX_DATA, fp) ) > 0 ) {
        PC_PRINTLNF("sendFile: packet number: %d ", numPackets);
        PC_PRINTLNF("length: %d", len);

        Packet *p = Packet::create(CMD_SYNCOLDEST, 0x00, len, d);
        PC_PRINTLNF("sendFile: packet checksum = %x", p->checkSum);
        btComm.sendPacket(p);
        delete p;
        
        for (int i = 0; i < len; i++) {
            PC_PRINTLNF("sendFile: packet[%d] = ", i);
            PC_PRINTLNF("%x", d[i]);   
        }
        
        PC_PRINTLNF("sendFile: sent packet of length %d", len);
        PC_PRINTLN("sendFile: waiting for ack...");
        
        Packet *resp;
        int n = btComm.receivePacket(&resp, TIMEOUT);
        if (n <= 0) {
            PC_PRINTLN("sendFile: timeout waiting for ack!");
            fclose(fp);
            return false;
        }
        
        if (resp->cmd != ACK) {
            PC_PRINTLN("sendFile: packet received was not an ack!");
            delete resp;
            fclose(fp);
            return false;
        }
        
        delete resp;
        
        PC_PRINTLN("sendFile: received ack!");
        numPackets++;
    }
    delete[] d;

    PC_PRINTLNF("sendFile: done sending %s in ", filename.c_str());
    PC_PRINTLNF("%d packets.", numPackets);
    // 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;
//    }
    
    fclose(fp);
    return true;
}

/* Returns absolute filename of the oldest log file on the SD card */
bool getOldestFile(string *oldest) 
{
    
    PC_PRINTLN("Finding oldest file...");
    
    // 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/");

    if (dp == NULL) {
      PC_PRINTLN("syncOldestSession: Error opening directory");
      return false;
    }

    while((dirp = readdir(dp)) != NULL) {
        char *strp = dirp->d_name;

        // 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, TIMEOUT);
        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);
        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");
    }
}