Swimate V2 without RTOS code

Dependencies:   Adafruit_GFX_128x64 DS3231 PinDetect SDFileSystem USBDevice mbed RealtimeMath MODSERIAL

Committer:
ellingjp
Date:
Mon Jun 09 04:55:16 2014 +0000
Revision:
24:f2503d1256ad
Parent:
22:9350752f5414
Using RTC filenames

Who changed what in which revision?

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