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
Child:
22:9350752f5414
Working sync

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ellingjp 21:2fa676f214fe 1 #include "comms.h"
ellingjp 21:2fa676f214fe 2 #include "debug.h"
ellingjp 21:2fa676f214fe 3
ellingjp 21:2fa676f214fe 4 const int Packet::HEADER_SIZE = 5;
ellingjp 21:2fa676f214fe 5
ellingjp 21:2fa676f214fe 6 /* If successful, loads p with a new packet. User is responsible for deleting.
ellingjp 21:2fa676f214fe 7 * Returns > 0 on success
ellingjp 21:2fa676f214fe 8 0 on timeout
ellingjp 21:2fa676f214fe 9 < 0 on error
ellingjp 21:2fa676f214fe 10 */
ellingjp 21:2fa676f214fe 11 int Comms::receivePacket(Packet **p, int timeout) {
ellingjp 21:2fa676f214fe 12 // PC_PRINTLN("receivePacket: getting header");
ellingjp 21:2fa676f214fe 13 uint8_t headerBuf[Packet::HEADER_SIZE];
ellingjp 21:2fa676f214fe 14 if (!getBytes(headerBuf, Packet::HEADER_SIZE, timeout))
ellingjp 21:2fa676f214fe 15 return 0;
ellingjp 21:2fa676f214fe 16
ellingjp 21:2fa676f214fe 17 uint8_t cmd = headerBuf[0];
ellingjp 21:2fa676f214fe 18 uint16_t packetNumber = headerBuf[1];
ellingjp 21:2fa676f214fe 19 uint16_t dataLength = headerBuf[3];
ellingjp 21:2fa676f214fe 20
ellingjp 21:2fa676f214fe 21 PC_PRINTLNF("receivePacket: cmd = %d", cmd);
ellingjp 21:2fa676f214fe 22 PC_PRINTLNF("receivePacket: packetNumber = %d", packetNumber);
ellingjp 21:2fa676f214fe 23 PC_PRINTLNF("receivePacket: dataLength = %d", dataLength);
ellingjp 21:2fa676f214fe 24
ellingjp 21:2fa676f214fe 25 uint8_t data[dataLength];
ellingjp 21:2fa676f214fe 26 if (!getBytes(data, dataLength, timeout))
ellingjp 21:2fa676f214fe 27 return 0;
ellingjp 21:2fa676f214fe 28
ellingjp 21:2fa676f214fe 29 PC_PRINTLN("receivePacket: getting checksum");
ellingjp 21:2fa676f214fe 30 uint16_t checkSum;
ellingjp 21:2fa676f214fe 31 if (!getBytes((uint8_t *) &checkSum, sizeof(checkSum), timeout))
ellingjp 21:2fa676f214fe 32 return 0;
ellingjp 21:2fa676f214fe 33
ellingjp 21:2fa676f214fe 34 PC_PRINTLN("receivePacket: verifying checksum");
ellingjp 21:2fa676f214fe 35 *p = Packet::createAndVerify(cmd, packetNumber, dataLength, data, checkSum);
ellingjp 21:2fa676f214fe 36 if (*p == NULL)
ellingjp 21:2fa676f214fe 37 return -1;
ellingjp 21:2fa676f214fe 38
ellingjp 21:2fa676f214fe 39 return 1;
ellingjp 21:2fa676f214fe 40 }
ellingjp 21:2fa676f214fe 41
ellingjp 21:2fa676f214fe 42 /* Sends packet p, and deletes it */
ellingjp 21:2fa676f214fe 43 void Comms::sendPacket(Packet *p) {
ellingjp 21:2fa676f214fe 44 sendBytes((uint8_t *)&p->cmd, sizeof(p->cmd));
ellingjp 21:2fa676f214fe 45 sendBytes((uint8_t *)&p->packetNumber, sizeof(p->packetNumber));
ellingjp 21:2fa676f214fe 46 sendBytes((uint8_t *)&p->dataLength, sizeof(p->dataLength));
ellingjp 21:2fa676f214fe 47 sendBytes((uint8_t *) p->data, p->dataLength);
ellingjp 21:2fa676f214fe 48 sendBytes((uint8_t *)&p->checkSum, sizeof(p->checkSum));
ellingjp 21:2fa676f214fe 49 }
ellingjp 21:2fa676f214fe 50
ellingjp 21:2fa676f214fe 51 void Comms::sendBytes(uint8_t *bytes, int nElms) {
ellingjp 21:2fa676f214fe 52 for (int i = 0; i < nElms; i++)
ellingjp 21:2fa676f214fe 53 bt.putc(bytes[i]);
ellingjp 21:2fa676f214fe 54 }
ellingjp 21:2fa676f214fe 55
ellingjp 21:2fa676f214fe 56 void Comms::sendByte(uint8_t byte) {
ellingjp 21:2fa676f214fe 57 bt.putc(byte);
ellingjp 21:2fa676f214fe 58 }
ellingjp 21:2fa676f214fe 59
ellingjp 21:2fa676f214fe 60 /* Loads buf with a byte from the bluetooth stream.
ellingjp 21:2fa676f214fe 61 * Returns true if successful, false on timeout. */
ellingjp 21:2fa676f214fe 62 bool Comms::getBytes(uint8_t *buf, int n, int timeout) {
ellingjp 21:2fa676f214fe 63 for (int i = 0; i < n; i++) {
ellingjp 21:2fa676f214fe 64 // PC_PRINTLNF("getBytes: waiting for byte %d", i);
ellingjp 21:2fa676f214fe 65 if (!getByte(buf+i, timeout)) {
ellingjp 21:2fa676f214fe 66 // PC_PRINTLN("getBytes: failed to get byte");
ellingjp 21:2fa676f214fe 67 return false;
ellingjp 21:2fa676f214fe 68 }
ellingjp 21:2fa676f214fe 69 // PC_PRINTLNF("getBytes: got byte %d", *(buf+i));
ellingjp 21:2fa676f214fe 70 }
ellingjp 21:2fa676f214fe 71
ellingjp 21:2fa676f214fe 72 // PC_PRINTLN("getBytes: got bytes");
ellingjp 21:2fa676f214fe 73 return true;
ellingjp 21:2fa676f214fe 74 }
ellingjp 21:2fa676f214fe 75
ellingjp 21:2fa676f214fe 76 /* Loads c with a byte from the bluetooth stream.
ellingjp 21:2fa676f214fe 77 * Returns true if successful, false on timeout. */
ellingjp 21:2fa676f214fe 78 bool Comms::getByte(uint8_t *byte, int timeout) {
ellingjp 21:2fa676f214fe 79 // PC_PRINTLN("getByte: getting byte");
ellingjp 21:2fa676f214fe 80 if (timeout != INT_MAX)
ellingjp 21:2fa676f214fe 81 timer.start();
ellingjp 21:2fa676f214fe 82
ellingjp 21:2fa676f214fe 83 // PC_PRINTLN("getByte: waiting for bt readable");
ellingjp 21:2fa676f214fe 84 // Spin until byte available or timeout
ellingjp 21:2fa676f214fe 85 while ( !bt.readable() )
ellingjp 21:2fa676f214fe 86 if (timer.read_ms() > timeout)
ellingjp 21:2fa676f214fe 87 return false;
ellingjp 21:2fa676f214fe 88
ellingjp 21:2fa676f214fe 89 // PC_PRINTLN("getByte: byte available");
ellingjp 21:2fa676f214fe 90 timer.stop();
ellingjp 21:2fa676f214fe 91 timer.reset();
ellingjp 21:2fa676f214fe 92 *byte = bt.getc();
ellingjp 21:2fa676f214fe 93
ellingjp 21:2fa676f214fe 94 // PC_PRINTLNF("getByte: byte read = %d", *byte);
ellingjp 21:2fa676f214fe 95 return true;
ellingjp 21:2fa676f214fe 96 }
ellingjp 21:2fa676f214fe 97
ellingjp 21:2fa676f214fe 98 /* Returns a new packet. Copies dataLength bytes from data, and verifies the checkSum.
ellingjp 21:2fa676f214fe 99 * If the given checkSum is incorrect, returns NULL.
ellingjp 21:2fa676f214fe 100 * User is responsible for deleting the returned packet. */
ellingjp 21:2fa676f214fe 101 Packet *Packet::createAndVerify(uint8_t cmd, uint16_t packetNumber, uint16_t dataLength, uint8_t *data, uint16_t checkSum) {
ellingjp 21:2fa676f214fe 102 if (dataLength > 0 && data == NULL)
ellingjp 21:2fa676f214fe 103 return NULL;
ellingjp 21:2fa676f214fe 104
ellingjp 21:2fa676f214fe 105 Packet *p = new Packet(cmd, packetNumber, dataLength, data);
ellingjp 21:2fa676f214fe 106 if (p->checkSum != checkSum)
ellingjp 21:2fa676f214fe 107 return NULL;
ellingjp 21:2fa676f214fe 108 else
ellingjp 21:2fa676f214fe 109 return p;
ellingjp 21:2fa676f214fe 110 }
ellingjp 21:2fa676f214fe 111
ellingjp 21:2fa676f214fe 112 /* Returns a new packet. Copies dataLength bytes from data, and generates the checksum.
ellingjp 21:2fa676f214fe 113 * User is responsible for deleting the returned packet. */
ellingjp 21:2fa676f214fe 114 Packet *Packet::create(uint8_t cmd, uint16_t packetNumber, uint16_t dataLength, uint8_t *data) {
ellingjp 21:2fa676f214fe 115 if (dataLength > 0 && data == NULL)
ellingjp 21:2fa676f214fe 116 return NULL;
ellingjp 21:2fa676f214fe 117
ellingjp 21:2fa676f214fe 118 return new Packet(cmd, packetNumber, dataLength, data);
ellingjp 21:2fa676f214fe 119 }
ellingjp 21:2fa676f214fe 120
ellingjp 21:2fa676f214fe 121 /* Copies dataLength bytes from data */
ellingjp 21:2fa676f214fe 122 Packet::Packet(uint8_t cmd, uint16_t packetNumber, uint16_t dataLength, uint8_t *data) {
ellingjp 21:2fa676f214fe 123 checkSum = 0;
ellingjp 21:2fa676f214fe 124
ellingjp 21:2fa676f214fe 125 this->cmd = cmd;
ellingjp 21:2fa676f214fe 126 this->packetNumber = packetNumber;
ellingjp 21:2fa676f214fe 127 this->dataLength = dataLength;
ellingjp 21:2fa676f214fe 128
ellingjp 21:2fa676f214fe 129 checkSum ^= cmd;
ellingjp 21:2fa676f214fe 130 checkSum ^= packetNumber;
ellingjp 21:2fa676f214fe 131 checkSum ^= dataLength;
ellingjp 21:2fa676f214fe 132
ellingjp 21:2fa676f214fe 133 this->data = new uint8_t[dataLength];
ellingjp 21:2fa676f214fe 134 for (int i = 0; i < dataLength; i++) {
ellingjp 21:2fa676f214fe 135 this->data[i] = data[i];
ellingjp 21:2fa676f214fe 136 checkSum ^= data[i];
ellingjp 21:2fa676f214fe 137 }
ellingjp 21:2fa676f214fe 138 }
ellingjp 21:2fa676f214fe 139
ellingjp 21:2fa676f214fe 140 Packet::~Packet() {
ellingjp 21:2fa676f214fe 141 delete[] data;
ellingjp 21:2fa676f214fe 142 }