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
sync.cpp
- Committer:
- ellingjp
- Date:
- 2014-06-07
- Revision:
- 21:2fa676f214fe
- Parent:
- 9:a711b5b34d73
- Child:
- 22:9350752f5414
File content as of revision 21:2fa676f214fe:
#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");
}
}