Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: Adafruit_GFX_128x64 DS3231 PinDetect SDFileSystem USBDevice mbed RealtimeMath MODSERIAL
Diff: sync.cpp
- Revision:
- 21:2fa676f214fe
- Parent:
- 9:a711b5b34d73
- Child:
- 22:9350752f5414
--- a/sync.cpp Thu Jun 05 19:03:42 2014 +0000
+++ b/sync.cpp Sat Jun 07 07:12:25 2014 +0000
@@ -1,39 +1,303 @@
#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"
-/*
- PACKET STRUCTURE:
-
- Command:
- [ 1 CMD | 17 SESSION_ID (optional) ]
-
- Response:
- [ 1 ACK/NACK | X Data (optional) ]
-
- Byte | Description
- ------------------
- 0x0 | ACK
- 0x1 | NACK
- 0x2 | Delete All
- 0x4 | Receive file
-*/
+enum state {IDLE, CAPTURE, SYNC};
+extern enum state State;
+extern DS3231 rtc;
+Timeout t;
-Serial 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;
}
-unsigned char get_command() {
+
+
+//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;
}
-void sync() {
- if(bt.readable()) {
- bt.putc(bt.getc());
- bt.putc('\n');
+/* 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;
+ }
+ }
}
- unsigned char cmd = get_command();
+ 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");
+ }
}
\ No newline at end of file