CSE477 / swimate_v2

Dependencies:   Adafruit_GFX_128x64 DS3231 PinDetect SDFileSystem USBDevice mbed RealtimeMath MODSERIAL

Committer:
ellingjp
Date:
Sat Jun 07 07:12:25 2014 +0000
Revision:
21:2fa676f214fe
Parent:
9:a711b5b34d73
Child:
22:9350752f5414
Working sync

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ellingjp 9:a711b5b34d73 1 #include "mbed.h"
ellingjp 9:a711b5b34d73 2 #include "sync.h"
ellingjp 21:2fa676f214fe 3 #include "DS3231.h"
ellingjp 21:2fa676f214fe 4 #include "Timeout.h"
ellingjp 21:2fa676f214fe 5 #include "SDFileSystem.h"
ellingjp 21:2fa676f214fe 6 #include "MODSERIAL.h"
ellingjp 21:2fa676f214fe 7 #include "debug.h"
ellingjp 21:2fa676f214fe 8 #include <string>
ellingjp 21:2fa676f214fe 9 #include <string.h>
ellingjp 21:2fa676f214fe 10 #include <stdlib.h>
ellingjp 21:2fa676f214fe 11 #include <stdio.h>
ellingjp 21:2fa676f214fe 12 #include <limits.h>
ellingjp 21:2fa676f214fe 13 #include "comms.h"
ellingjp 9:a711b5b34d73 14
ellingjp 21:2fa676f214fe 15 enum state {IDLE, CAPTURE, SYNC};
ellingjp 21:2fa676f214fe 16 extern enum state State;
ellingjp 21:2fa676f214fe 17 extern DS3231 rtc;
ellingjp 21:2fa676f214fe 18 Timeout t;
ellingjp 9:a711b5b34d73 19
ellingjp 21:2fa676f214fe 20 //MODSERIAL bt(P0_19, P0_18); // tx, rx
ellingjp 21:2fa676f214fe 21 Comms btComm;
ellingjp 21:2fa676f214fe 22 uint16_t packetSeq = 0;
ellingjp 9:a711b5b34d73 23
ellingjp 21:2fa676f214fe 24 bool sync_init()
ellingjp 21:2fa676f214fe 25 {
ellingjp 9:a711b5b34d73 26 return true;
ellingjp 9:a711b5b34d73 27 }
ellingjp 9:a711b5b34d73 28
ellingjp 21:2fa676f214fe 29
ellingjp 21:2fa676f214fe 30
ellingjp 21:2fa676f214fe 31 //void setRtc(packet *p)
ellingjp 21:2fa676f214fe 32 //{
ellingjp 21:2fa676f214fe 33 // int dayOfWeek=0, date, month, year, hours, minutes, seconds;
ellingjp 21:2fa676f214fe 34 // uint16_t len;
ellingjp 21:2fa676f214fe 35 // len = getLen();
ellingjp 21:2fa676f214fe 36 // int i = 0;
ellingjp 21:2fa676f214fe 37 // for(i = 0; i < len; i++)
ellingjp 21:2fa676f214fe 38 // {
ellingjp 21:2fa676f214fe 39 // buff[i] = bt.getc();
ellingjp 21:2fa676f214fe 40 // }
ellingjp 21:2fa676f214fe 41 // buff[i] = 0; // end the string with a zero
ellingjp 21:2fa676f214fe 42 // sscanf(buff, "%04d-%02d-%02d %02d:%02d:%02d",&year,&month,&date,&hours,&minutes,&seconds);
ellingjp 21:2fa676f214fe 43 // rtc.setDate(dayOfWeek, date, month, year);
ellingjp 21:2fa676f214fe 44 // rtc.setTime(hours, minutes, seconds);
ellingjp 21:2fa676f214fe 45 // //sendResponse(CMD_RTCSET, ACK);
ellingjp 21:2fa676f214fe 46 //}
ellingjp 21:2fa676f214fe 47
ellingjp 21:2fa676f214fe 48 //void listSessions()
ellingjp 21:2fa676f214fe 49 //{ //todo buffer this with buff
ellingjp 21:2fa676f214fe 50 // DIR *dp;
ellingjp 21:2fa676f214fe 51 // struct dirent *dirp;
ellingjp 21:2fa676f214fe 52 // dp = opendir("/sd/");
ellingjp 21:2fa676f214fe 53 // while((dirp = readdir(dp)) != NULL) {
ellingjp 21:2fa676f214fe 54 // bt.puts(dirp->d_name);
ellingjp 21:2fa676f214fe 55 // bt.putc(',');
ellingjp 21:2fa676f214fe 56 // //todo: put size here?
ellingjp 21:2fa676f214fe 57 // bt.puts("\r\\n");
ellingjp 21:2fa676f214fe 58 // }
ellingjp 21:2fa676f214fe 59 // closedir(dp);
ellingjp 21:2fa676f214fe 60 //}
ellingjp 21:2fa676f214fe 61
ellingjp 21:2fa676f214fe 62 //void syncSession()
ellingjp 21:2fa676f214fe 63 //{
ellingjp 21:2fa676f214fe 64 // //sendResponse(buf[0], resp);
ellingjp 21:2fa676f214fe 65 // //populate packet:
ellingjp 21:2fa676f214fe 66 // //1 byte CMD_SYNCSESSION 0x03
ellingjp 21:2fa676f214fe 67 // //2 bytes packet number
ellingjp 21:2fa676f214fe 68 // //2 bytes current packet's data's length
ellingjp 21:2fa676f214fe 69 // //2 bytes checksum
ellingjp 21:2fa676f214fe 70 //}
ellingjp 21:2fa676f214fe 71 //
ellingjp 21:2fa676f214fe 72
ellingjp 21:2fa676f214fe 73 /* Sends a file over BT stream. Returns
ellingjp 21:2fa676f214fe 74 * true on success, false on failure. */
ellingjp 21:2fa676f214fe 75 bool sendFile(string filename)
ellingjp 21:2fa676f214fe 76 {
ellingjp 21:2fa676f214fe 77 PC_PRINTLNF("sendFile: Trying to open file %s", filename.c_str());
ellingjp 21:2fa676f214fe 78 FILE *fp = fopen(filename.c_str(), "r");
ellingjp 21:2fa676f214fe 79
ellingjp 21:2fa676f214fe 80 if (fp == NULL) {
ellingjp 21:2fa676f214fe 81 PC_PRINTLNF("sendFile: Error opening file %s", filename.c_str());
ellingjp 21:2fa676f214fe 82 return false;
ellingjp 21:2fa676f214fe 83 }
ellingjp 21:2fa676f214fe 84
ellingjp 21:2fa676f214fe 85 fseek(fp, 0L, SEEK_END);
ellingjp 21:2fa676f214fe 86 int file_size = ftell(fp);
ellingjp 21:2fa676f214fe 87 fseek(fp, 0L, SEEK_SET);
ellingjp 21:2fa676f214fe 88
ellingjp 21:2fa676f214fe 89 Packet *firstPacket = Packet::create(CMD_SYNCOLDEST, 0x00, sizeof(file_size), (uint8_t *) &file_size);
ellingjp 21:2fa676f214fe 90 btComm.sendPacket(firstPacket);
ellingjp 21:2fa676f214fe 91
ellingjp 21:2fa676f214fe 92 PC_PRINTLNF("sendFile: first packet checksum = %x", firstPacket->checkSum);
ellingjp 21:2fa676f214fe 93
ellingjp 21:2fa676f214fe 94 delete firstPacket;
ellingjp 9:a711b5b34d73 95
ellingjp 21:2fa676f214fe 96 Packet *res;
ellingjp 21:2fa676f214fe 97 int n = btComm.receivePacket(&res, TIMEOUT);
ellingjp 21:2fa676f214fe 98 if (n <= 0) {
ellingjp 21:2fa676f214fe 99 PC_PRINTLN("sendFile: timeout waiting for ack!");
ellingjp 21:2fa676f214fe 100 fclose(fp);
ellingjp 21:2fa676f214fe 101 return false;
ellingjp 21:2fa676f214fe 102 }
ellingjp 21:2fa676f214fe 103
ellingjp 21:2fa676f214fe 104 if (res->cmd != ACK) {
ellingjp 21:2fa676f214fe 105 PC_PRINTLN("sendFile: packet received was not an ack!");
ellingjp 21:2fa676f214fe 106 delete res;
ellingjp 21:2fa676f214fe 107 fclose(fp);
ellingjp 21:2fa676f214fe 108 return false;
ellingjp 21:2fa676f214fe 109 }
ellingjp 21:2fa676f214fe 110
ellingjp 21:2fa676f214fe 111 delete res;
ellingjp 21:2fa676f214fe 112
ellingjp 21:2fa676f214fe 113 uint8_t *d = new uint8_t[PACKET_MAX_DATA];
ellingjp 21:2fa676f214fe 114
ellingjp 21:2fa676f214fe 115 PC_PRINTLN("sendFile: created buffer");
ellingjp 21:2fa676f214fe 116 int len;
ellingjp 21:2fa676f214fe 117 int numPackets = 0;
ellingjp 21:2fa676f214fe 118 while ( (len = fread(d, 1, PACKET_MAX_DATA, fp) ) > 0 ) {
ellingjp 21:2fa676f214fe 119 PC_PRINTLNF("sendFile: packet number: %d ", numPackets);
ellingjp 21:2fa676f214fe 120 PC_PRINTLNF("length: %d", len);
ellingjp 21:2fa676f214fe 121
ellingjp 21:2fa676f214fe 122 Packet *p = Packet::create(CMD_SYNCOLDEST, 0x00, len, d);
ellingjp 21:2fa676f214fe 123 PC_PRINTLNF("sendFile: packet checksum = %x", p->checkSum);
ellingjp 21:2fa676f214fe 124 btComm.sendPacket(p);
ellingjp 21:2fa676f214fe 125 delete p;
ellingjp 21:2fa676f214fe 126
ellingjp 21:2fa676f214fe 127 for (int i = 0; i < len; i++) {
ellingjp 21:2fa676f214fe 128 PC_PRINTLNF("sendFile: packet[%d] = ", i);
ellingjp 21:2fa676f214fe 129 PC_PRINTLNF("%x", d[i]);
ellingjp 21:2fa676f214fe 130 }
ellingjp 21:2fa676f214fe 131
ellingjp 21:2fa676f214fe 132 PC_PRINTLNF("sendFile: sent packet of length %d", len);
ellingjp 21:2fa676f214fe 133 PC_PRINTLN("sendFile: waiting for ack...");
ellingjp 21:2fa676f214fe 134
ellingjp 21:2fa676f214fe 135 Packet *resp;
ellingjp 21:2fa676f214fe 136 int n = btComm.receivePacket(&resp, TIMEOUT);
ellingjp 21:2fa676f214fe 137 if (n <= 0) {
ellingjp 21:2fa676f214fe 138 PC_PRINTLN("sendFile: timeout waiting for ack!");
ellingjp 21:2fa676f214fe 139 fclose(fp);
ellingjp 21:2fa676f214fe 140 return false;
ellingjp 21:2fa676f214fe 141 }
ellingjp 21:2fa676f214fe 142
ellingjp 21:2fa676f214fe 143 if (resp->cmd != ACK) {
ellingjp 21:2fa676f214fe 144 PC_PRINTLN("sendFile: packet received was not an ack!");
ellingjp 21:2fa676f214fe 145 delete resp;
ellingjp 21:2fa676f214fe 146 fclose(fp);
ellingjp 21:2fa676f214fe 147 return false;
ellingjp 21:2fa676f214fe 148 }
ellingjp 21:2fa676f214fe 149
ellingjp 21:2fa676f214fe 150 delete resp;
ellingjp 21:2fa676f214fe 151
ellingjp 21:2fa676f214fe 152 PC_PRINTLN("sendFile: received ack!");
ellingjp 21:2fa676f214fe 153 numPackets++;
ellingjp 21:2fa676f214fe 154 }
ellingjp 21:2fa676f214fe 155 delete[] d;
ellingjp 21:2fa676f214fe 156
ellingjp 21:2fa676f214fe 157 PC_PRINTLNF("sendFile: done sending %s in ", filename.c_str());
ellingjp 21:2fa676f214fe 158 PC_PRINTLNF("%d packets.", numPackets);
ellingjp 21:2fa676f214fe 159 // Appears to be a bug where feof isn't defined, so no error checking :(
ellingjp 21:2fa676f214fe 160 // if (!feof(fp)) {
ellingjp 21:2fa676f214fe 161 // PC_PRINTLNF("sendFile: Error reading file %s", absolute_filename.c_str());
ellingjp 21:2fa676f214fe 162 // return false;
ellingjp 21:2fa676f214fe 163 // }
ellingjp 21:2fa676f214fe 164
ellingjp 21:2fa676f214fe 165 fclose(fp);
ellingjp 21:2fa676f214fe 166 return true;
ellingjp 9:a711b5b34d73 167 }
ellingjp 9:a711b5b34d73 168
ellingjp 21:2fa676f214fe 169 /* Returns absolute filename of the oldest log file on the SD card */
ellingjp 21:2fa676f214fe 170 bool getOldestFile(string *oldest)
ellingjp 21:2fa676f214fe 171 {
ellingjp 21:2fa676f214fe 172
ellingjp 21:2fa676f214fe 173 PC_PRINTLN("Finding oldest file...");
ellingjp 21:2fa676f214fe 174
ellingjp 21:2fa676f214fe 175 // Ensure all fields get set to zero
ellingjp 21:2fa676f214fe 176 long long file_time = {0};
ellingjp 21:2fa676f214fe 177 long long oldest_time = LLONG_MAX; // ensures first file gets set to oldest
ellingjp 21:2fa676f214fe 178 string oldest_file;
ellingjp 21:2fa676f214fe 179
ellingjp 21:2fa676f214fe 180 DIR *dp;
ellingjp 21:2fa676f214fe 181 struct dirent *dirp;
ellingjp 21:2fa676f214fe 182 dp = opendir("/sd/");
ellingjp 21:2fa676f214fe 183
ellingjp 21:2fa676f214fe 184 if (dp == NULL) {
ellingjp 21:2fa676f214fe 185 PC_PRINTLN("syncOldestSession: Error opening directory");
ellingjp 21:2fa676f214fe 186 return false;
ellingjp 21:2fa676f214fe 187 }
ellingjp 21:2fa676f214fe 188
ellingjp 21:2fa676f214fe 189 while((dirp = readdir(dp)) != NULL) {
ellingjp 21:2fa676f214fe 190 char *strp = dirp->d_name;
ellingjp 21:2fa676f214fe 191
ellingjp 21:2fa676f214fe 192 // Verify we are looking at a .log file
ellingjp 21:2fa676f214fe 193 char ext[5];
ellingjp 21:2fa676f214fe 194 memcpy(ext, strp+strlen(strp) - 4, 5);
ellingjp 21:2fa676f214fe 195 if (strncmp(ext, ".log", 4) == 0) {
ellingjp 21:2fa676f214fe 196 PC_PRINTLNF("syncOldestSession: reading file %s", dirp->d_name);
ellingjp 21:2fa676f214fe 197
ellingjp 21:2fa676f214fe 198 file_time = strtoll(strp, NULL, 10);
ellingjp 21:2fa676f214fe 199
ellingjp 21:2fa676f214fe 200 // If file time is older than oldest time, set the oldest file
ellingjp 21:2fa676f214fe 201 // to the current file
ellingjp 21:2fa676f214fe 202 if (file_time < oldest_time) {
ellingjp 21:2fa676f214fe 203 PC_PRINTLN("syncOldestSession: updating oldest file");
ellingjp 21:2fa676f214fe 204 oldest_time = file_time;
ellingjp 21:2fa676f214fe 205 oldest_file = strp;
ellingjp 21:2fa676f214fe 206 }
ellingjp 21:2fa676f214fe 207 }
ellingjp 9:a711b5b34d73 208 }
ellingjp 9:a711b5b34d73 209
ellingjp 21:2fa676f214fe 210 PC_PRINTLNF("getOldestFile: prepending /sd/ to %s", oldest_file.c_str());
ellingjp 21:2fa676f214fe 211 *oldest = "/sd/";
ellingjp 21:2fa676f214fe 212 *oldest += oldest_file;
ellingjp 21:2fa676f214fe 213
ellingjp 21:2fa676f214fe 214 closedir(dp);
ellingjp 21:2fa676f214fe 215 return true;
ellingjp 21:2fa676f214fe 216 }
ellingjp 21:2fa676f214fe 217
ellingjp 21:2fa676f214fe 218 bool syncOldestSession()
ellingjp 21:2fa676f214fe 219 {
ellingjp 21:2fa676f214fe 220 string oldest;
ellingjp 21:2fa676f214fe 221
ellingjp 21:2fa676f214fe 222 if (getOldestFile(&oldest))
ellingjp 21:2fa676f214fe 223 return sendFile(oldest);
ellingjp 21:2fa676f214fe 224
ellingjp 21:2fa676f214fe 225 return false;
ellingjp 21:2fa676f214fe 226 }
ellingjp 21:2fa676f214fe 227
ellingjp 21:2fa676f214fe 228 bool deleteOldestSession()
ellingjp 21:2fa676f214fe 229 {
ellingjp 21:2fa676f214fe 230 string oldest;
ellingjp 21:2fa676f214fe 231
ellingjp 21:2fa676f214fe 232 if (getOldestFile(&oldest)) {
ellingjp 21:2fa676f214fe 233 PC_PRINTLNF("deleteOldestSession: deleting %s", oldest.c_str());
ellingjp 21:2fa676f214fe 234
ellingjp 21:2fa676f214fe 235 if (remove(oldest.c_str()) == 0) {
ellingjp 21:2fa676f214fe 236 PC_PRINTLN("deleteOldestSession: delete success");
ellingjp 21:2fa676f214fe 237 // send ack
ellingjp 21:2fa676f214fe 238 return true;
ellingjp 21:2fa676f214fe 239 }
ellingjp 21:2fa676f214fe 240 }
ellingjp 21:2fa676f214fe 241
ellingjp 21:2fa676f214fe 242 // send ack
ellingjp 21:2fa676f214fe 243
ellingjp 21:2fa676f214fe 244 return false;
ellingjp 21:2fa676f214fe 245 }
ellingjp 21:2fa676f214fe 246
ellingjp 21:2fa676f214fe 247 void sync()
ellingjp 21:2fa676f214fe 248 {
ellingjp 21:2fa676f214fe 249 PC_PRINTLN("Entered sync mode...");
ellingjp 21:2fa676f214fe 250 while(State == SYNC) {
ellingjp 21:2fa676f214fe 251 PC_PRINTLN("Waiting for packet...")
ellingjp 21:2fa676f214fe 252 Packet *p;
ellingjp 21:2fa676f214fe 253 int ret = btComm.receivePacket(&p, TIMEOUT);
ellingjp 21:2fa676f214fe 254 if (ret == 0) {
ellingjp 21:2fa676f214fe 255 PC_PRINTLN("Timeout!");
ellingjp 21:2fa676f214fe 256 continue;
ellingjp 21:2fa676f214fe 257 } else if (ret < 0) {
ellingjp 21:2fa676f214fe 258 PC_PRINTLN("Received bad packet :(");
ellingjp 21:2fa676f214fe 259 continue;
ellingjp 21:2fa676f214fe 260 }
ellingjp 21:2fa676f214fe 261
ellingjp 21:2fa676f214fe 262 PC_PRINTLNF("cmd: %x", p->cmd);
ellingjp 21:2fa676f214fe 263 PC_PRINTLNF("pnum: %x", p->packetNumber);
ellingjp 21:2fa676f214fe 264 PC_PRINTLNF("len: %x", p->dataLength);
ellingjp 21:2fa676f214fe 265 for (int i = 0; i < p->dataLength; i++) {
ellingjp 21:2fa676f214fe 266 PC_PRINTF("data[%d]: ", i);
ellingjp 21:2fa676f214fe 267 PC_PRINTLNF("%x", p->data[i]);
ellingjp 21:2fa676f214fe 268 }
ellingjp 21:2fa676f214fe 269 PC_PRINTLNF("check: %x", p->checkSum);
ellingjp 21:2fa676f214fe 270 switch(p->cmd) {
ellingjp 21:2fa676f214fe 271 case CMD_SYNCOLDEST:
ellingjp 21:2fa676f214fe 272 if (!syncOldestSession())
ellingjp 21:2fa676f214fe 273 PC_PRINTLN("Sync oldest session failed!");
ellingjp 21:2fa676f214fe 274 break;
ellingjp 21:2fa676f214fe 275 case CMD_DELETEOLDEST:
ellingjp 21:2fa676f214fe 276 if (!deleteOldestSession())
ellingjp 21:2fa676f214fe 277 PC_PRINTLN("Delete oldest session failed!");
ellingjp 21:2fa676f214fe 278 break;
ellingjp 21:2fa676f214fe 279 // case CMD_RTCSET:
ellingjp 21:2fa676f214fe 280 // //setRtc(p);
ellingjp 21:2fa676f214fe 281 // break;
ellingjp 21:2fa676f214fe 282 // case CMD_LISTSESSIONS:
ellingjp 21:2fa676f214fe 283 // listSessions();
ellingjp 21:2fa676f214fe 284 // break;
ellingjp 21:2fa676f214fe 285 // case CMD_SYNCSESSION:
ellingjp 21:2fa676f214fe 286 // syncSession();
ellingjp 21:2fa676f214fe 287 // break;
ellingjp 21:2fa676f214fe 288 // case CMD_DELETESESSION:
ellingjp 21:2fa676f214fe 289 // deleteSession();
ellingjp 21:2fa676f214fe 290 // break;
ellingjp 21:2fa676f214fe 291 // case CMD_DONE:
ellingjp 21:2fa676f214fe 292 // bt.putc(CMD_DONE);
ellingjp 21:2fa676f214fe 293 // //sendResponse(CMD_DONE, ACK);
ellingjp 21:2fa676f214fe 294 // State = IDLE;
ellingjp 21:2fa676f214fe 295 // break;
ellingjp 21:2fa676f214fe 296 // default: break;
ellingjp 21:2fa676f214fe 297 }
ellingjp 21:2fa676f214fe 298
ellingjp 21:2fa676f214fe 299 PC_PRINTLN("Deleting received packet...");
ellingjp 21:2fa676f214fe 300 delete p;
ellingjp 21:2fa676f214fe 301 PC_PRINTLN("Ready for new packet");
ellingjp 21:2fa676f214fe 302 }
ellingjp 9:a711b5b34d73 303 }