Michael Ling / ExoController

Dependents:   Data-Management-Honka

Committer:
mzling
Date:
Wed Apr 15 01:50:50 2015 +0000
Revision:
17:80affee96096
Parent:
16:b6b2c7b0f1c9
Child:
18:34ccf02fdbe7
Pushed phone message back 2

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mzling 2:be605799793f 1 #include "mbed.h"
mzling 2:be605799793f 2 #include "MODSERIAL.h"
mzling 2:be605799793f 3 #include "BluetoothComm.h"
mzling 5:92659a4c2f89 4 #include "initDatabed.h"
mzling 2:be605799793f 5 #include <string>
mzling 2:be605799793f 6 #include <map>
mzling 16:b6b2c7b0f1c9 7
mzling 9:8024861fccac 8 BluetoothComm::BluetoothComm(PinName tx, PinName rx): _rn42(tx, rx), _len(0), _counter(0), _inMsg(false), _numVars(27), _numReadOnlyParams(12), _escapesNeeded(8)
mzling 2:be605799793f 9 {
mzling 5:92659a4c2f89 10
mzling 6:721f5e8a794d 11 /* Make sure baud rate is correct--rn42 cannot be read if code and MBED have different baud rates! */
mzling 6:721f5e8a794d 12 //_rn42.baud(9600);
mzling 16:b6b2c7b0f1c9 13
mzling 6:721f5e8a794d 14 _rn42.baud(115200);
mzling 2:be605799793f 15 int temp1[] = {0,1,2,3,4,8,9,10, -1};
mzling 2:be605799793f 16
mzling 3:14050370593a 17 for (int i = 0; i < _escapesNeeded+1; i++) {
mzling 3:14050370593a 18 _escapeNeeded[i] = temp1[i];
mzling 2:be605799793f 19 }
mzling 2:be605799793f 20
mzling 2:be605799793f 21
mzling 2:be605799793f 22 std::string temp2[] = {"KPStance", "KPSwing", "KPStanding", "KPSitting", "KPStandUp", "KPSitdown", "KDStance", "KDSwing",
mzling 2:be605799793f 23 "KDStanding", "KDSitting", "KDStandUp", "KDSitDown", "StandingAngle", "SittingAngle", "BentForwardAngle", "ForwardAngle", "RearAngle",
mzling 9:8024861fccac 24 "IMUAngle", "KneeFullRetract", "KneeFullExtend", "LockTime", "Rate", "StandupAsst", "StandupTime", "SitdownAsst", "SitdownTime", "WalkAngle",
mzling 9:8024861fccac 25 "TorsoAng", "LKneeAng", "RKneeAng", "LHipAng", "RHipAng", "LHipTorque", "RHipTorque", "ExoAndKneeStates", "TorsoRefAngle", "LHipRefAngle",
mzling 9:8024861fccac 26 "RHipRefAngle", "Charge"};
mzling 2:be605799793f 27 //Populate the map of indices to param names
mzling 3:14050370593a 28 for (int j = 0; j < (_numVars + _numReadOnlyParams); j += 1) {
mzling 3:14050370593a 29 _indexMap[j] = temp2[j];
mzling 2:be605799793f 30 }
mzling 2:be605799793f 31
mzling 3:14050370593a 32
mzling 16:b6b2c7b0f1c9 33 // write_params_to_sd_card();
mzling 16:b6b2c7b0f1c9 34
mzling 4:7e3bbf896e78 35 int temp4[] = {0x01fe, 0x02ac, 0x02ff, 0x0180, 0x0012, 0x0010, 0x0020, 0x00bf, 0x023f, 0x0123, 0x03a2, 0x10};
mzling 16:b6b2c7b0f1c9 36 //readData.write(_numReadOnlyParams, temp4);
mzling 4:7e3bbf896e78 37 for (int k = 0; k < _numReadOnlyParams; k += 1) {
mzling 4:7e3bbf896e78 38 _paramMap[_indexMap[_numVars + k]] = temp4[k];
mzling 4:7e3bbf896e78 39 }
mzling 16:b6b2c7b0f1c9 40
mzling 16:b6b2c7b0f1c9 41 // write_data_to_sd_card();
mzling 3:14050370593a 42 //Fill the parameter map with data from SD card
mzling 16:b6b2c7b0f1c9 43 // read_data_from_sd();
mzling 16:b6b2c7b0f1c9 44
mzling 16:b6b2c7b0f1c9 45 //read_params_from_sd();
mzling 12:50f6f9ed5cc6 46 pc.printf("Finished BTComm init\r\n");
mzling 2:be605799793f 47
mzling 2:be605799793f 48 }
mzling 2:be605799793f 49
mzling 3:14050370593a 50 /**
mzling 3:14050370593a 51 * Reads read-only data from SD card, and fills in the parameter map.
mzling 3:14050370593a 52 * @author Michael Ling
mzling 3:14050370593a 53 * @date 2/4/2015
mzling 3:14050370593a 54 */
mzling 16:b6b2c7b0f1c9 55 /**
mzling 3:14050370593a 56 void BluetoothComm::read_data_from_sd()
mzling 3:14050370593a 57 {
mzling 3:14050370593a 58
mzling 3:14050370593a 59 int *arr = readData.read(_numReadOnlyParams, arr);
mzling 3:14050370593a 60 for (int i = 0; i < _numReadOnlyParams; i += 1) {
mzling 3:14050370593a 61 _paramMap[_indexMap[i + _numVars]] = arr[i];
mzling 16:b6b2c7b0f1c9 62
mzling 2:be605799793f 63 }
mzling 16:b6b2c7b0f1c9 64
mzling 16:b6b2c7b0f1c9 65 }*/
mzling 2:be605799793f 66
mzling 3:14050370593a 67 /**
mzling 3:14050370593a 68 * Reads editable parameters from SD card, and fills in the parameter map
mzling 3:14050370593a 69 * @author Michael Ling
mzling 3:14050370593a 70 * @date 2/4/2015
mzling 3:14050370593a 71 */
mzling 16:b6b2c7b0f1c9 72 /**
mzling 3:14050370593a 73 void BluetoothComm::read_params_from_sd()
mzling 3:14050370593a 74 {
mzling 3:14050370593a 75 int *arr = param.read(_numVars, arr);
mzling 3:14050370593a 76 for (int i = 0; i < _numVars; i += 1) {
mzling 3:14050370593a 77 _paramMap[_indexMap[i]] = arr[i];
mzling 2:be605799793f 78 }
mzling 16:b6b2c7b0f1c9 79
mzling 16:b6b2c7b0f1c9 80 }*/
mzling 2:be605799793f 81
mzling 3:14050370593a 82 /**
mzling 3:14050370593a 83 * Calculates parity--0 if c even, 1 if odd
mzling 3:14050370593a 84 * @param c The short that we want to calculate parity of
mzling 3:14050370593a 85 * @author Michael Ling
mzling 3:14050370593a 86 * @date 2/4/2015
mzling 3:14050370593a 87 */
mzling 2:be605799793f 88 bool BluetoothComm::parity(short c)
mzling 2:be605799793f 89 {
mzling 2:be605799793f 90 bool p = false;
mzling 2:be605799793f 91 while (c != 0) {
mzling 2:be605799793f 92 p = !p;
mzling 2:be605799793f 93 c = (short) (c & (c-1));
mzling 2:be605799793f 94 }
mzling 2:be605799793f 95 return p;
mzling 2:be605799793f 96 }
mzling 2:be605799793f 97
mzling 3:14050370593a 98 /**
mzling 3:14050370593a 99 * Calculates checksum of char array, sum of all chars in array
mzling 3:14050370593a 100 * @param b The char array to be summed up
mzling 3:14050370593a 101 * @param len Length of the array b
mzling 3:14050370593a 102 * @author Michael Ling
mzling 3:14050370593a 103 * @date 2/4/2015
mzling 3:14050370593a 104 */
mzling 3:14050370593a 105 char* BluetoothComm::get_checksum(char* b, int len)
mzling 2:be605799793f 106 {
mzling 2:be605799793f 107 char* checksum = (char*)malloc(3*sizeof(char));
mzling 2:be605799793f 108 short sum = 0;
mzling 2:be605799793f 109 for (int i = 0; i < len; i += 1) {
mzling 2:be605799793f 110 sum += ((short) b[i] & 0xff);
mzling 2:be605799793f 111 }
mzling 2:be605799793f 112 checksum[1] = (char) ((sum >> 8) & 0xff);
mzling 2:be605799793f 113 checksum[2] = (char) (sum & 0xff);
mzling 2:be605799793f 114 char check = (char) (sum & 0xff);
mzling 2:be605799793f 115 //Sets escape character if the checksum contains START or END
mzling 2:be605799793f 116 if (check == START || check == END) {
mzling 2:be605799793f 117 checksum[0] = 1;
mzling 2:be605799793f 118 checksum[2] = (char) (checksum[2] & 0x1);
mzling 2:be605799793f 119 } else {
mzling 2:be605799793f 120 checksum[0] = 0;
mzling 2:be605799793f 121 }
mzling 2:be605799793f 122 return checksum;
mzling 2:be605799793f 123 }
mzling 2:be605799793f 124
mzling 3:14050370593a 125 /**
mzling 3:14050370593a 126 * Sends error message.
mzling 3:14050370593a 127 * @param errCode character representation of the failure-causing error
mzling 3:14050370593a 128 * @author Michael Ling
mzling 3:14050370593a 129 * @data 2/4/2015
mzling 3:14050370593a 130 */
mzling 3:14050370593a 131 void BluetoothComm::send_error(char errCode)
mzling 2:be605799793f 132 {
mzling 3:14050370593a 133 _rn42.putc(START);
mzling 3:14050370593a 134 _rn42.putc(errCode);
mzling 3:14050370593a 135 _rn42.putc(END);
mzling 3:14050370593a 136 _rn42.putc(0);
mzling 3:14050370593a 137 _rn42.putc(0);
mzling 3:14050370593a 138 _rn42.putc(0);
mzling 2:be605799793f 139 }
mzling 16:b6b2c7b0f1c9 140
mzling 2:be605799793f 141
mzling 3:14050370593a 142 /**
mzling 3:14050370593a 143 * Sends the specified char array through the _rn42 Bluetooth connection.
mzling 3:14050370593a 144 * @param cmd The char array to be sent
mzling 3:14050370593a 145 * @author Michael Ling
mzling 3:14050370593a 146 * @date 2/4/2015
mzling 3:14050370593a 147 */
mzling 2:be605799793f 148 void BluetoothComm::send(char *cmd)
mzling 2:be605799793f 149 {
mzling 2:be605799793f 150 for (int i = 0; i < 50; i++) {
mzling 3:14050370593a 151 _rn42.putc(cmd[i]);
mzling 2:be605799793f 152 }
mzling 2:be605799793f 153 }
mzling 2:be605799793f 154
mzling 3:14050370593a 155 /**
mzling 3:14050370593a 156 * Sets the parameter map, based on the input map NEWVALUES
mzling 3:14050370593a 157 * @param newValues A map of strings to shorts to be copied to _paramMap
mzling 3:14050370593a 158 * @author Michael Ling
mzling 3:14050370593a 159 * @date 2/4/2015
mzling 3:14050370593a 160 */
mzling 3:14050370593a 161 void BluetoothComm::set_values(std::map<string, short> newValues)
mzling 3:14050370593a 162 {
mzling 2:be605799793f 163
mzling 2:be605799793f 164 for (std::map<string, short>::iterator it = newValues.begin(); it != newValues.end(); ++it) {
mzling 3:14050370593a 165 _paramMap[it->first] = it->second;
mzling 2:be605799793f 166 }
mzling 2:be605799793f 167 }
mzling 2:be605799793f 168
mzling 3:14050370593a 169 /**
mzling 3:14050370593a 170 * Writes the editable params. stored in _paramMap to the SD card
mzling 3:14050370593a 171 * @author Michael Ling
mzling 3:14050370593a 172 * @date 2/4/2015
mzling 3:14050370593a 173 */
mzling 16:b6b2c7b0f1c9 174 /**
mzling 3:14050370593a 175 void BluetoothComm::write_params_to_sd_card()
mzling 3:14050370593a 176 {
mzling 2:be605799793f 177
mzling 3:14050370593a 178 int paramValues[_numVars];
mzling 3:14050370593a 179 for (int i = 0; i < _numVars; i += 1) {
mzling 3:14050370593a 180 paramValues[i] = (int) _paramMap[_indexMap[i]];
mzling 2:be605799793f 181 }
mzling 3:14050370593a 182 param.write(_numVars, paramValues);
mzling 2:be605799793f 183
mzling 16:b6b2c7b0f1c9 184 }*/
mzling 2:be605799793f 185
mzling 3:14050370593a 186 /**
mzling 3:14050370593a 187 * Write the read-only values stored in _paramMap to the SD card
mzling 3:14050370593a 188 * @author Michael Ling
mzling 3:14050370593a 189 * @date 2/4/2015
mzling 3:14050370593a 190 */
mzling 16:b6b2c7b0f1c9 191 /**
mzling 3:14050370593a 192 void BluetoothComm::write_data_to_sd_card()
mzling 3:14050370593a 193 {
mzling 3:14050370593a 194 int dataValues[_numReadOnlyParams];
mzling 3:14050370593a 195 for (int i = 0; i < _numReadOnlyParams; i += 1) {
mzling 3:14050370593a 196 dataValues[i] = (int) _paramMap[_indexMap[i + _numVars]];
mzling 3:14050370593a 197 // printf("Index %d of dataValues set to %x\r\n", i, dataValues[i]);
mzling 2:be605799793f 198 }
mzling 3:14050370593a 199 readData.write(_numReadOnlyParams, dataValues);
mzling 16:b6b2c7b0f1c9 200 }*/
mzling 2:be605799793f 201
mzling 3:14050370593a 202 /**
mzling 3:14050370593a 203 * Sends the paramList with START/END, parity bits, and a checksum
mzling 3:14050370593a 204 * @param paramList List of parameters to be sent over Bluetooth, represented as a char array
mzling 16:b6b2c7b0f1c9 205 * @param message The message we want to send to Ctrlbed
mzling 16:b6b2c7b0f1c9 206 * @param dataOut Circular buffer that allow communication with Ctrlbed
mzling 3:14050370593a 207 * @author Michael Ling
mzling 3:14050370593a 208 * @date 2/4/2015
mzling 3:14050370593a 209 */
mzling 14:ac9949a0aff5 210 void BluetoothComm::send_values(char* paramList, char *message, short *dataOut)
mzling 2:be605799793f 211 {
mzling 3:14050370593a 212 char msg[2*_numVars+6];
mzling 2:be605799793f 213 int len=2;
mzling 2:be605799793f 214 //printf("Sending values \r\n");
mzling 2:be605799793f 215 msg[0] = START;
mzling 2:be605799793f 216 msg[1] = 0;
mzling 3:14050370593a 217 for (int i=0; i < _numVars; i++) {
mzling 15:a492356f5485 218
mzling 2:be605799793f 219 if (paramList[i] != 0xff) {
mzling 2:be605799793f 220 short s = (short)((i << 8) | paramList[i]);
mzling 3:14050370593a 221 //printf("In send_values, calculating parity of %x\r\n", s);
mzling 2:be605799793f 222 if (parity(s)) {
mzling 2:be605799793f 223 //printf("%x requires TRUE parity bit\r\n", s);
mzling 2:be605799793f 224 msg[len] = (char)(i | 0x40);
mzling 2:be605799793f 225 len += 1;
mzling 2:be605799793f 226 } else {
mzling 2:be605799793f 227 //printf("%x requires FALSE parity bit\r\n", s);
mzling 2:be605799793f 228 msg[len] = (char)i;
mzling 2:be605799793f 229 len += 1;
mzling 2:be605799793f 230 }
mzling 2:be605799793f 231 msg[len] = paramList[i];
mzling 2:be605799793f 232 len += 1;
mzling 2:be605799793f 233 }
mzling 2:be605799793f 234 }
mzling 2:be605799793f 235 msg[len] = END;
mzling 2:be605799793f 236 len += 1;
mzling 3:14050370593a 237 char* checksum = get_checksum(msg, len);
mzling 2:be605799793f 238 msg[len] = checksum[0];
mzling 2:be605799793f 239 msg[len+1] = checksum[1];
mzling 2:be605799793f 240 msg[len+2] = checksum[2];
mzling 2:be605799793f 241 len += 3;
mzling 16:b6b2c7b0f1c9 242 //This loop sends a reply to the phone
mzling 2:be605799793f 243 for (int j = 0; j < len; j++) {
mzling 15:a492356f5485 244 printf("Sending char %x \r\n", msg[j]);
mzling 3:14050370593a 245 _rn42.putc(msg[j]);
mzling 10:235c0b81c4c7 246
mzling 10:235c0b81c4c7 247 }
mzling 16:b6b2c7b0f1c9 248 //This loop passes the original write message to the ctrlbed
mzling 16:b6b2c7b0f1c9 249 //Each pair of characters is converted to a short, with orders reversed.
mzling 16:b6b2c7b0f1c9 250 //This is so that casting the short* back to char* restores the original message.
mzling 10:235c0b81c4c7 251 if (dataOut != NULL) {
mzling 17:80affee96096 252 int ind = 2;
mzling 10:235c0b81c4c7 253 int j;
mzling 10:235c0b81c4c7 254 for (j = 0; j < len-1; j+=2) {
mzling 14:ac9949a0aff5 255 dataOut[ind] = (message[j+1]<<8)|message[j];
mzling 16:b6b2c7b0f1c9 256
mzling 13:67492109a66d 257 ind += 1;
mzling 10:235c0b81c4c7 258 }
mzling 16:b6b2c7b0f1c9 259 //If the message has an odd number of characters
mzling 10:235c0b81c4c7 260 if (j < len) {
mzling 14:ac9949a0aff5 261 dataOut[ind] = message[j];
mzling 16:b6b2c7b0f1c9 262
mzling 10:235c0b81c4c7 263 }
mzling 15:a492356f5485 264 for (int k=0; k<len;k++) {
mzling 15:a492356f5485 265 printf("Index %d: %x\r\n", k, dataOut[k]);
mzling 15:a492356f5485 266 }
mzling 10:235c0b81c4c7 267
mzling 2:be605799793f 268 }
mzling 3:14050370593a 269 memcpy(_lastCmd, msg, 50);
mzling 2:be605799793f 270 free(checksum);
mzling 2:be605799793f 271 return ;
mzling 2:be605799793f 272 }
mzling 2:be605799793f 273
mzling 3:14050370593a 274 /**
mzling 3:14050370593a 275 * Sends readOnly Parameters, with START/END and checksum
mzling 3:14050370593a 276 * @author Michael Ling
mzling 3:14050370593a 277 * @date 2/4/2015
mzling 3:14050370593a 278 */
mzling 3:14050370593a 279 void BluetoothComm::send_read_only_values()
mzling 2:be605799793f 280 {
mzling 16:b6b2c7b0f1c9 281
mzling 3:14050370593a 282 int msgLen = 2*_numReadOnlyParams+_escapesNeeded+7;
mzling 2:be605799793f 283 char message[msgLen];
mzling 2:be605799793f 284 message[0] = START;
mzling 2:be605799793f 285 message[1] = 0;
mzling 2:be605799793f 286 message[2] = READONLY_IND;
mzling 2:be605799793f 287 int msgInd = 3;
mzling 2:be605799793f 288 int escapes = 0;
mzling 3:14050370593a 289 for (int i = 0; i < _numReadOnlyParams; i++) {
mzling 3:14050370593a 290 if (i == _escapeNeeded[escapes]) {
mzling 3:14050370593a 291 char conflict = (char)(_paramMap[_indexMap[i+_numVars]] & 0xff);
mzling 2:be605799793f 292 escapes += 1;
mzling 3:14050370593a 293 message[msgInd+1] = (char) (_paramMap[_indexMap[i+_numVars]] >> 8);
mzling 2:be605799793f 294 if (conflict == (char) 0xfe) {
mzling 2:be605799793f 295 message[msgInd] = 1;
mzling 2:be605799793f 296 message[msgInd+2] = 0xfc;
mzling 2:be605799793f 297 } else if (conflict == (char) 0xff) {
mzling 2:be605799793f 298 message[msgInd] = 1;
mzling 2:be605799793f 299 message[msgInd+2] = 0xfd;
mzling 2:be605799793f 300 } else {
mzling 2:be605799793f 301 message[msgInd] = 0;
mzling 2:be605799793f 302 message[msgInd+2] = conflict;
mzling 2:be605799793f 303 }
mzling 2:be605799793f 304 msgInd += 3;
mzling 2:be605799793f 305 } else {
mzling 3:14050370593a 306 message[msgInd] = (char) (_paramMap[_indexMap[i+_numVars]] >> 8);
mzling 3:14050370593a 307 message[msgInd+1] = (char) (_paramMap[_indexMap[i+_numVars]] & 0xff);
mzling 2:be605799793f 308 msgInd += 2;
mzling 2:be605799793f 309 }
mzling 2:be605799793f 310 }
mzling 2:be605799793f 311 message[msgLen-4] = END;
mzling 3:14050370593a 312 char* checksum = get_checksum(message, msgLen-3);
mzling 2:be605799793f 313 message[msgLen-3] = checksum[0];
mzling 2:be605799793f 314 message[msgLen-2] = checksum[1];
mzling 2:be605799793f 315 message[msgLen-1] = checksum[2];
mzling 2:be605799793f 316 for (int j=0; j < msgLen; j++) {
mzling 3:14050370593a 317 _rn42.putc(message[j]);
mzling 2:be605799793f 318 }
mzling 3:14050370593a 319 memcpy(_lastCmd, message, 50);
mzling 2:be605799793f 320 free(checksum);
mzling 2:be605799793f 321
mzling 2:be605799793f 322 }
mzling 2:be605799793f 323
mzling 3:14050370593a 324 /**
mzling 3:14050370593a 325 * Checks the message with length len. Checks for START and END in correct spots, parity, all data and variable byte in proper range, and correct checksum
mzling 3:14050370593a 326 * @param message The received message to check
mzling 3:14050370593a 327 * @param len Length of the message
mzling 3:14050370593a 328 * @author Michael Ling
mzling 3:14050370593a 329 * @date 2/4/2015
mzling 3:14050370593a 330 */
mzling 3:14050370593a 331 bool BluetoothComm::msg_check(char* message, int len)
mzling 2:be605799793f 332 {
mzling 2:be605799793f 333 if (message[0] != START) {
mzling 3:14050370593a 334 send_error(START_ERR);
mzling 2:be605799793f 335 return false;
mzling 2:be605799793f 336 }
mzling 2:be605799793f 337 if (message[len-4] != END) {
mzling 3:14050370593a 338 send_error(END_ERR);
mzling 2:be605799793f 339 return false;
mzling 2:be605799793f 340 }
mzling 2:be605799793f 341 bool write = message[2] & 0x80;
mzling 2:be605799793f 342 for (int i=2; i < len-5; i+=2) {
mzling 2:be605799793f 343 if (i == 2 && message[i] == READONLY_IND) {
mzling 2:be605799793f 344 break;
mzling 2:be605799793f 345 }
mzling 2:be605799793f 346 if (i == (len-5) && message[i] == READONLY_IND) {
mzling 2:be605799793f 347 break;
mzling 2:be605799793f 348 }
mzling 2:be605799793f 349 if (((message[i] & 0x80) !=0) && !write) {
mzling 3:14050370593a 350 send_error((char)(((message[i] & 0x3f) << 3) | RW_ERR));
mzling 2:be605799793f 351 return false;
mzling 2:be605799793f 352 }
mzling 2:be605799793f 353 if (((message[i] & 0x80) != 0x80) && write) {
mzling 3:14050370593a 354 send_error((char)(((message[i] & 0x3f) << 3) | RW_ERR));
mzling 2:be605799793f 355 return false;
mzling 2:be605799793f 356 }
mzling 2:be605799793f 357 short s;
mzling 2:be605799793f 358 if (write) {
mzling 2:be605799793f 359 s = (short) ((message[i] << 8) | message[i+1]);
mzling 2:be605799793f 360 } else {
mzling 2:be605799793f 361 s = (short) (message[i] << 8);
mzling 2:be605799793f 362 }
mzling 2:be605799793f 363 bool parity1 = (s & 0x4000) != 0;
mzling 2:be605799793f 364
mzling 2:be605799793f 365 if (parity1 != parity(s & 0x4000)) {
mzling 3:14050370593a 366 send_error((char) (((message[i] & 0xbf) << 3) | PARITY_ERR));
mzling 2:be605799793f 367 return false;
mzling 2:be605799793f 368 }
mzling 2:be605799793f 369
mzling 2:be605799793f 370 char c = message[i] & 0x3f;
mzling 2:be605799793f 371 char c2 = message[i+1];
mzling 3:14050370593a 372 if ((int) c < 0 || (int) c > _numVars) {
mzling 3:14050370593a 373 send_error((char) (((message[i] & 0xbf) << 3) | VAR_ERR));
mzling 2:be605799793f 374 return false;
mzling 2:be605799793f 375 }
mzling 2:be605799793f 376 if ((int) c2 < 0 || (int) c2 > 100) {
mzling 3:14050370593a 377 send_error((char) (((message[i] & 0xbf) << 3) | DATA_ERR));
mzling 2:be605799793f 378 return false;
mzling 2:be605799793f 379 }
mzling 2:be605799793f 380 }
mzling 3:14050370593a 381 char* checksum = get_checksum(message, len-3);
mzling 2:be605799793f 382 if (checksum[0] != message[len-3]) {
mzling 2:be605799793f 383 free(checksum);
mzling 3:14050370593a 384 send_error(CHECKSUM_ERR);
mzling 2:be605799793f 385 return false;
mzling 2:be605799793f 386 }
mzling 2:be605799793f 387 if (checksum[1] != message[len-2]) {
mzling 2:be605799793f 388 free(checksum);
mzling 3:14050370593a 389 send_error(CHECKSUM_ERR);
mzling 2:be605799793f 390 return false;
mzling 2:be605799793f 391 }
mzling 2:be605799793f 392 if (checksum[2] != message[len-1]) {
mzling 2:be605799793f 393 free(checksum);
mzling 3:14050370593a 394 send_error(CHECKSUM_ERR);
mzling 2:be605799793f 395 return false;
mzling 2:be605799793f 396 }
mzling 2:be605799793f 397 free(checksum);
mzling 2:be605799793f 398
mzling 2:be605799793f 399 return true;
mzling 2:be605799793f 400 }
mzling 2:be605799793f 401
mzling 3:14050370593a 402 /**
mzling 3:14050370593a 403 * Checks a received readOnly message
mzling 3:14050370593a 404 * @param message The readonly message received
mzling 3:14050370593a 405 * @param len Length of the message
mzling 3:14050370593a 406 * @author Michael Ling
mzling 3:14050370593a 407 * @date 2/4/2015
mzling 3:14050370593a 408 */
mzling 3:14050370593a 409 void BluetoothComm::process_read_only(char* message, int len)
mzling 2:be605799793f 410 {
mzling 16:b6b2c7b0f1c9 411
mzling 3:14050370593a 412 if (!msg_check(message, len)) {
mzling 6:721f5e8a794d 413 printf("msg_check failed on readonly! \r\n");
mzling 2:be605799793f 414 return;
mzling 2:be605799793f 415 }
mzling 3:14050370593a 416 _failures = 0;
mzling 2:be605799793f 417
mzling 3:14050370593a 418 send_read_only_values();
mzling 2:be605799793f 419 }
mzling 2:be605799793f 420
mzling 3:14050370593a 421 /**
mzling 3:14050370593a 422 * Checks received READ message, and places requested data into an array
mzling 3:14050370593a 423 * @param message The received READ request as a char array
mzling 3:14050370593a 424 * @param len Length of the READ message
mzling 3:14050370593a 425 * @author Michael Ling
mzling 3:14050370593a 426 * @date 2/4/2015
mzling 3:14050370593a 427 */
mzling 3:14050370593a 428 void BluetoothComm::process_read(char* message, int len)
mzling 2:be605799793f 429 {
mzling 2:be605799793f 430 //If the received message is an error message, resend the last command
mzling 3:14050370593a 431 if (message[2] == END) {
mzling 3:14050370593a 432 _failures += 1;
mzling 3:14050370593a 433 if (_failures < 5) {
mzling 3:14050370593a 434 send(_lastCmd);
mzling 2:be605799793f 435 } else {
mzling 3:14050370593a 436 _failures = 0;
mzling 2:be605799793f 437 }
mzling 2:be605799793f 438 return;
mzling 2:be605799793f 439 }
mzling 3:14050370593a 440 if (!msg_check(message, len)) {
mzling 2:be605799793f 441 return;
mzling 2:be605799793f 442 }
mzling 6:721f5e8a794d 443 //PASS MSG TO CTRLBED
mzling 3:14050370593a 444 _failures = 0;
mzling 3:14050370593a 445 char paramList[_numVars];
mzling 3:14050370593a 446 memset(paramList, 0xff, _numVars);
mzling 2:be605799793f 447
mzling 2:be605799793f 448 for (int i=2; i < len-5; i++) {
mzling 2:be605799793f 449 char msg = message[i] & 0xbf;
mzling 2:be605799793f 450 if ((msg & 0x80) != 0) {
mzling 2:be605799793f 451 return;
mzling 2:be605799793f 452 }
mzling 2:be605799793f 453
mzling 2:be605799793f 454 int index = msg & 0xff;
mzling 3:14050370593a 455 paramList[index] = _paramMap[_indexMap[index]];
mzling 2:be605799793f 456
mzling 2:be605799793f 457 }
mzling 2:be605799793f 458 if (message[len-5] == READONLY_IND) {
mzling 3:14050370593a 459 send_read_only_values();
mzling 2:be605799793f 460 }
mzling 14:ac9949a0aff5 461 send_values(paramList, NULL, NULL);
mzling 2:be605799793f 462 }
mzling 2:be605799793f 463
mzling 3:14050370593a 464 /**
mzling 3:14050370593a 465 * Checks received WRITE message and writes to paramMap/SDCard
mzling 3:14050370593a 466 * @param message The received WRITE message
mzling 3:14050370593a 467 * @param len Length of the WRITE message
mzling 16:b6b2c7b0f1c9 468 * @param dataOut Buffer that contains message for Ctrlbed
mzling 3:14050370593a 469 * @author Michael Ling
mzling 3:14050370593a 470 * @date 2/4/2015
mzling 3:14050370593a 471 */
mzling 10:235c0b81c4c7 472 void BluetoothComm::process_write(char* message, int len, short* dataOut)
mzling 2:be605799793f 473 {
mzling 3:14050370593a 474 if (message[2] == END) {
mzling 3:14050370593a 475 _failures += 1;
mzling 3:14050370593a 476 if (_failures < 5) {
mzling 3:14050370593a 477 send(_lastCmd);
mzling 2:be605799793f 478 } else {
mzling 3:14050370593a 479 _failures = 0;
mzling 2:be605799793f 480 }
mzling 2:be605799793f 481 return;
mzling 2:be605799793f 482 }
mzling 10:235c0b81c4c7 483 //dataOut = message;
mzling 3:14050370593a 484 if (!msg_check(message, len)) {
mzling 6:721f5e8a794d 485 printf("msg_check failed on write! \r\n");
mzling 2:be605799793f 486 return;
mzling 2:be605799793f 487 }
mzling 16:b6b2c7b0f1c9 488
mzling 3:14050370593a 489 char paramList[_numVars];
mzling 3:14050370593a 490 memset(paramList, 0xff, _numVars);
mzling 16:b6b2c7b0f1c9 491 //Strips received message of parity and write bits, sets paramMap to the new values, then passes the phone/ctrlbed messages to sendValues
mzling 2:be605799793f 492 for (int i=2; i < len-5; i+=2) {
mzling 2:be605799793f 493 char msg = message[i] & 0xbf;
mzling 2:be605799793f 494 if ((msg & 0x80) != 0x80) {
mzling 2:be605799793f 495 return;
mzling 2:be605799793f 496 }
mzling 2:be605799793f 497 int index = msg & 0x7f;
mzling 3:14050370593a 498 _paramMap[_indexMap[index]] = message[i+1];
mzling 2:be605799793f 499 paramList[index] = message[i+1];
mzling 2:be605799793f 500 //printf("Wrote %x to index %d of localValues \r\n", localValues[index], index);
mzling 2:be605799793f 501
mzling 2:be605799793f 502 }
mzling 14:ac9949a0aff5 503 send_values(paramList, message, dataOut);
mzling 14:ac9949a0aff5 504
mzling 16:b6b2c7b0f1c9 505 // write_params_to_sd_card();
mzling 16:b6b2c7b0f1c9 506
mzling 2:be605799793f 507 }
mzling 2:be605799793f 508
mzling 3:14050370593a 509 /**
mzling 3:14050370593a 510 * Checks if received message is a read, write or readonly
mzling 3:14050370593a 511 * @param message The received message
mzling 3:14050370593a 512 * @param len Length of the message
mzling 16:b6b2c7b0f1c9 513 * @param dataOut Buffer for sending to ctrlbed
mzling 3:14050370593a 514 * @author Michael Ling
mzling 3:14050370593a 515 * @date 2/4/2015
mzling 3:14050370593a 516 */
mzling 10:235c0b81c4c7 517 void BluetoothComm::process (char* message, int len, short* dataOut)
mzling 2:be605799793f 518 {
mzling 2:be605799793f 519 char c = message[2];
mzling 4:7e3bbf896e78 520 for (int i =0; i < len; i++) {
mzling 6:721f5e8a794d 521 //printf("Message character: %x \r\n", message[i]);
mzling 4:7e3bbf896e78 522 }
mzling 2:be605799793f 523 if (c == READONLY_IND) {
mzling 3:14050370593a 524 process_read_only(message, len);
mzling 2:be605799793f 525 return;
mzling 2:be605799793f 526 }
mzling 2:be605799793f 527 if ((c & 0x80) == 0) {
mzling 6:721f5e8a794d 528 //printf("Is a read\r\n");
mzling 3:14050370593a 529 process_read(message, len);
mzling 2:be605799793f 530 return;
mzling 2:be605799793f 531 } else {
mzling 10:235c0b81c4c7 532 process_write(message, len, dataOut);
mzling 2:be605799793f 533 return;
mzling 2:be605799793f 534 }
mzling 2:be605799793f 535 }
mzling 2:be605799793f 536
mzling 2:be605799793f 537 //Warning: do not put print statements in the function attachment(); it will interfere with receiving messages
mzling 3:14050370593a 538 /**
mzling 3:14050370593a 539 * Scans for data received through Bluetooth, and passes it on if it detects a message-like chunk. Should be run via an interuupt.
mzling 16:b6b2c7b0f1c9 540 * @param dataOut Buffer for sending to Ctrlbed
mzling 3:14050370593a 541 * @author Michael Ling
mzling 3:14050370593a 542 * @date 2/4/2015
mzling 3:14050370593a 543 */
mzling 10:235c0b81c4c7 544 void BluetoothComm::attachment(short* dataOut)
mzling 2:be605799793f 545 {
mzling 13:67492109a66d 546
mzling 7:d4a32c830e11 547 // pc.printf("Entered attachment\r\n");
mzling 3:14050370593a 548 if (_rn42.readable()) {
mzling 3:14050370593a 549 _data=_rn42.getc();
mzling 2:be605799793f 550
mzling 3:14050370593a 551 // if (_data != NULL) {
mzling 3:14050370593a 552 char b = _data & 0xff;
mzling 3:14050370593a 553 //printf("Got char: %x \r\n", b);
mzling 3:14050370593a 554 if (b != NULL or _inMsg) {
mzling 3:14050370593a 555 // printf("Got char non null: %x \r\n", b);
mzling 3:14050370593a 556 }
mzling 3:14050370593a 557 //This marks the START of a message
mzling 3:14050370593a 558 if (_inMsg == false and b == START) {
mzling 16:b6b2c7b0f1c9 559 //boardLed4 = 1;
mzling 3:14050370593a 560 _inMsg = true;
mzling 3:14050370593a 561 _counter = 3;
mzling 3:14050370593a 562 _curMsg[_len] = b;
mzling 3:14050370593a 563 _len += 1;
mzling 3:14050370593a 564 } else if (_inMsg == true and b == START) {
mzling 3:14050370593a 565 _inMsg = false;
mzling 3:14050370593a 566 _counter = 0;
mzling 3:14050370593a 567 memset(_curMsg, 0, 50);
mzling 3:14050370593a 568 _rn42.rxBufferFlush();
mzling 10:235c0b81c4c7 569 process(_msg, _len, dataOut);
mzling 3:14050370593a 570 _len = 0;
mzling 3:14050370593a 571 } else if (_inMsg || _counter > 0 ) {
mzling 3:14050370593a 572 _curMsg[_len] = b;
mzling 3:14050370593a 573 _len += 1;
mzling 3:14050370593a 574 if (!_inMsg) {
mzling 3:14050370593a 575 _counter -= 1;
mzling 2:be605799793f 576 }
mzling 3:14050370593a 577 //Marks end of message, and starts processing
mzling 3:14050370593a 578 if (_counter <= 0) {
mzling 3:14050370593a 579 memset(_msg, 0, 50);
mzling 3:14050370593a 580 memcpy(_msg, _curMsg, 50);
mzling 3:14050370593a 581 memset(_curMsg, 0, 50);
mzling 3:14050370593a 582 _rn42.rxBufferFlush();
mzling 10:235c0b81c4c7 583 process(_msg, _len, dataOut);
mzling 3:14050370593a 584 _len = 0;
mzling 2:be605799793f 585 }
mzling 3:14050370593a 586 }
mzling 3:14050370593a 587 if (b == END) {
mzling 3:14050370593a 588 _inMsg = false;
mzling 2:be605799793f 589
mzling 16:b6b2c7b0f1c9 590
mzling 3:14050370593a 591 }
mzling 16:b6b2c7b0f1c9 592
mzling 2:be605799793f 593
mzling 3:14050370593a 594 }
mzling 2:be605799793f 595 }