IM920 (920MHz wireless module) protocol parser

Committer:
hideakitai
Date:
Mon Apr 11 12:41:10 2016 +0000
Revision:
0:ee7d2910f5ea
IM920 (920MHz wireless module) protocol parser

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hideakitai 0:ee7d2910f5ea 1 #pragma once
hideakitai 0:ee7d2910f5ea 2 #include "mbed.h"
hideakitai 0:ee7d2910f5ea 3 #include <queue>
hideakitai 0:ee7d2910f5ea 4
hideakitai 0:ee7d2910f5ea 5 #define kAsciiCR 0x0D
hideakitai 0:ee7d2910f5ea 6 #define kAsciiLF 0x0A
hideakitai 0:ee7d2910f5ea 7
hideakitai 0:ee7d2910f5ea 8 class IM920 : public Serial
hideakitai 0:ee7d2910f5ea 9 {
hideakitai 0:ee7d2910f5ea 10 typedef enum StateIm920 {
hideakitai 0:ee7d2910f5ea 11 kStateNode = 0,
hideakitai 0:ee7d2910f5ea 12 kStateParentId,
hideakitai 0:ee7d2910f5ea 13 kStateRssi,
hideakitai 0:ee7d2910f5ea 14 kStateData,
hideakitai 0:ee7d2910f5ea 15 kStateCRLF
hideakitai 0:ee7d2910f5ea 16 } StateIm920;
hideakitai 0:ee7d2910f5ea 17
hideakitai 0:ee7d2910f5ea 18 typedef struct Im920Packet {
hideakitai 0:ee7d2910f5ea 19 int node;
hideakitai 0:ee7d2910f5ea 20 int parent_id;
hideakitai 0:ee7d2910f5ea 21 int rssi;
hideakitai 0:ee7d2910f5ea 22 int data[8];
hideakitai 0:ee7d2910f5ea 23 } Im920Packet;
hideakitai 0:ee7d2910f5ea 24
hideakitai 0:ee7d2910f5ea 25 typedef struct Im920PacketAscii {
hideakitai 0:ee7d2910f5ea 26 char node[3];
hideakitai 0:ee7d2910f5ea 27 char parent_id[5];
hideakitai 0:ee7d2910f5ea 28 char rssi[3];
hideakitai 0:ee7d2910f5ea 29 char data[8][3];
hideakitai 0:ee7d2910f5ea 30 } Im920PacketAscii;
hideakitai 0:ee7d2910f5ea 31
hideakitai 0:ee7d2910f5ea 32 public:
hideakitai 0:ee7d2910f5ea 33
hideakitai 0:ee7d2910f5ea 34 IM920(PinName tx, PinName rx, int baudrate)
hideakitai 0:ee7d2910f5ea 35 : mbed::Serial(tx, rx)
hideakitai 0:ee7d2910f5ea 36 , pc(NULL)
hideakitai 0:ee7d2910f5ea 37 {
hideakitai 0:ee7d2910f5ea 38 this->baud(baudrate);
hideakitai 0:ee7d2910f5ea 39 this->attach(this, &IM920::push_byte);
hideakitai 0:ee7d2910f5ea 40 }
hideakitai 0:ee7d2910f5ea 41 virtual ~IM920()
hideakitai 0:ee7d2910f5ea 42 {
hideakitai 0:ee7d2910f5ea 43 if (pc) delete pc;
hideakitai 0:ee7d2910f5ea 44 }
hideakitai 0:ee7d2910f5ea 45
hideakitai 0:ee7d2910f5ea 46 void push_byte() { byte_buff.push(this->getc()); }
hideakitai 0:ee7d2910f5ea 47 void pop_byte() { byte_buff.pop(); }
hideakitai 0:ee7d2910f5ea 48
hideakitai 0:ee7d2910f5ea 49 void pop() { readBuffer_.pop(); }
hideakitai 0:ee7d2910f5ea 50
hideakitai 0:ee7d2910f5ea 51 int available() { return (int)readBuffer_.size(); }
hideakitai 0:ee7d2910f5ea 52
hideakitai 0:ee7d2910f5ea 53 void dump()
hideakitai 0:ee7d2910f5ea 54 {
hideakitai 0:ee7d2910f5ea 55 while(byte_buff.size())
hideakitai 0:ee7d2910f5ea 56 {
hideakitai 0:ee7d2910f5ea 57 if(pc) pc->printf("%c", (char)byte_buff.front());
hideakitai 0:ee7d2910f5ea 58 byte_buff.pop();
hideakitai 0:ee7d2910f5ea 59 }
hideakitai 0:ee7d2910f5ea 60 }
hideakitai 0:ee7d2910f5ea 61
hideakitai 0:ee7d2910f5ea 62 virtual void setDebugSerial(Serial* s) { pc = s; }
hideakitai 0:ee7d2910f5ea 63
hideakitai 0:ee7d2910f5ea 64 void send(const char* format)
hideakitai 0:ee7d2910f5ea 65 { this->Serial::printf(format); }
hideakitai 0:ee7d2910f5ea 66 template <typename A>
hideakitai 0:ee7d2910f5ea 67 void send(const char* format, A &a)
hideakitai 0:ee7d2910f5ea 68 { this->Serial::printf(format, a); }
hideakitai 0:ee7d2910f5ea 69 template <typename A, typename B>
hideakitai 0:ee7d2910f5ea 70 void send(const char* format, A &a, B &b)
hideakitai 0:ee7d2910f5ea 71 { this->Serial::printf(format, a, b); }
hideakitai 0:ee7d2910f5ea 72 template <typename A, typename B, typename C>
hideakitai 0:ee7d2910f5ea 73 void send(const char* format, A &a, B &b, C &c)
hideakitai 0:ee7d2910f5ea 74 { this->Serial::printf(format, a, b, c); }
hideakitai 0:ee7d2910f5ea 75
hideakitai 0:ee7d2910f5ea 76 const Im920Packet& getPacket() { return readBuffer_.front(); }
hideakitai 0:ee7d2910f5ea 77 const int& getNwNode() { return readBuffer_.front().node; }
hideakitai 0:ee7d2910f5ea 78 const int& getNwParentId() { return readBuffer_.front().parent_id; }
hideakitai 0:ee7d2910f5ea 79 const int& getNwRssi() { return readBuffer_.front().rssi; }
hideakitai 0:ee7d2910f5ea 80 const int* getDataPtr() { return (int*)readBuffer_.front().data; }
hideakitai 0:ee7d2910f5ea 81 uint8_t getData(int idx) { return readBuffer_.front().data[idx]; }
hideakitai 0:ee7d2910f5ea 82
hideakitai 0:ee7d2910f5ea 83 void enableWriteFlash() { send("ENWR\r\n"); }
hideakitai 0:ee7d2910f5ea 84 void disableWriteFlash() { send("DSWR\r\n"); }
hideakitai 0:ee7d2910f5ea 85 void deleteParentId() { send("ERID\r\n"); }
hideakitai 0:ee7d2910f5ea 86 void writeParentId(int id) { send("SRID %04x\r\n", id); }
hideakitai 0:ee7d2910f5ea 87 void requestParentId() { send("RRID\r\n"); }
hideakitai 0:ee7d2910f5ea 88 void writeWirelessPower(int n) { send("STPO %1d\r\n", n); }
hideakitai 0:ee7d2910f5ea 89 void writeWirelessSpeed(int n) { send("STRT %1d\r\n", n); }
hideakitai 0:ee7d2910f5ea 90 void writeBaudrate(int n) { send("SBRT %1d\r\n", n); }
hideakitai 0:ee7d2910f5ea 91 void writeChannel(int n) { send("STCH %02d\r\n", n); }
hideakitai 0:ee7d2910f5ea 92 void reset() { send("SRST\r\n"); }
hideakitai 0:ee7d2910f5ea 93
hideakitai 0:ee7d2910f5ea 94 void dumpPacket()
hideakitai 0:ee7d2910f5ea 95 {
hideakitai 0:ee7d2910f5ea 96 if(available())
hideakitai 0:ee7d2910f5ea 97 {
hideakitai 0:ee7d2910f5ea 98 if(pc)
hideakitai 0:ee7d2910f5ea 99 {
hideakitai 0:ee7d2910f5ea 100 Im920Packet& p = readBuffer_.front();
hideakitai 0:ee7d2910f5ea 101 pc->printf("packet dump >> %02x,%04x,%02x:", p.node, p.parent_id, p.rssi);
hideakitai 0:ee7d2910f5ea 102 for (int i=0; i<7; i++) pc->printf("%02x,", p.data[i]);
hideakitai 0:ee7d2910f5ea 103 pc->printf("%02x\r\n", p.data[7]);
hideakitai 0:ee7d2910f5ea 104 }
hideakitai 0:ee7d2910f5ea 105 readBuffer_.pop();
hideakitai 0:ee7d2910f5ea 106 }
hideakitai 0:ee7d2910f5ea 107 else
hideakitai 0:ee7d2910f5ea 108 if(pc) pc->printf("[Error] No Packet Available!!\n");
hideakitai 0:ee7d2910f5ea 109 }
hideakitai 0:ee7d2910f5ea 110
hideakitai 0:ee7d2910f5ea 111 void parse()
hideakitai 0:ee7d2910f5ea 112 {
hideakitai 0:ee7d2910f5ea 113 if (byte_buff.size() <= 0) return;
hideakitai 0:ee7d2910f5ea 114
hideakitai 0:ee7d2910f5ea 115 static bool bUnderParsing = false;
hideakitai 0:ee7d2910f5ea 116 static int cnt = 0;
hideakitai 0:ee7d2910f5ea 117 static int dcnt = 0;
hideakitai 0:ee7d2910f5ea 118 static Im920PacketAscii pa;
hideakitai 0:ee7d2910f5ea 119 static StateIm920 state = kStateNode;
hideakitai 0:ee7d2910f5ea 120
hideakitai 0:ee7d2910f5ea 121 while (byte_buff.size() > 0)
hideakitai 0:ee7d2910f5ea 122 {
hideakitai 0:ee7d2910f5ea 123 char data = (char)byte_buff.front();
hideakitai 0:ee7d2910f5ea 124
hideakitai 0:ee7d2910f5ea 125 if (isCorrupted((int)data)) {
hideakitai 0:ee7d2910f5ea 126 state = kStateNode;
hideakitai 0:ee7d2910f5ea 127 bUnderParsing = false;
hideakitai 0:ee7d2910f5ea 128 return;
hideakitai 0:ee7d2910f5ea 129 }
hideakitai 0:ee7d2910f5ea 130
hideakitai 0:ee7d2910f5ea 131 if (!bUnderParsing)
hideakitai 0:ee7d2910f5ea 132 {
hideakitai 0:ee7d2910f5ea 133 for (int i=0; i<5; i++) pa.parent_id[i] = (char)0;
hideakitai 0:ee7d2910f5ea 134 for (int i=0; i<3; i++) {
hideakitai 0:ee7d2910f5ea 135 pa.node[i] = pa.rssi[i] = (char)0;
hideakitai 0:ee7d2910f5ea 136 for (int j=0; j<8; j++) pa.data[j][i] = (char)0;
hideakitai 0:ee7d2910f5ea 137 }
hideakitai 0:ee7d2910f5ea 138 dcnt = cnt = 0;
hideakitai 0:ee7d2910f5ea 139 bUnderParsing = true;
hideakitai 0:ee7d2910f5ea 140 }
hideakitai 0:ee7d2910f5ea 141
hideakitai 0:ee7d2910f5ea 142 switch(state)
hideakitai 0:ee7d2910f5ea 143 {
hideakitai 0:ee7d2910f5ea 144 case kStateNode:
hideakitai 0:ee7d2910f5ea 145 {
hideakitai 0:ee7d2910f5ea 146 if (data == ',') {
hideakitai 0:ee7d2910f5ea 147 state = kStateParentId;
hideakitai 0:ee7d2910f5ea 148 dcnt = cnt = 0;
hideakitai 0:ee7d2910f5ea 149 } else {
hideakitai 0:ee7d2910f5ea 150 pa.node[cnt++] = data;
hideakitai 0:ee7d2910f5ea 151 }
hideakitai 0:ee7d2910f5ea 152 break;
hideakitai 0:ee7d2910f5ea 153 }
hideakitai 0:ee7d2910f5ea 154 case kStateParentId:
hideakitai 0:ee7d2910f5ea 155 {
hideakitai 0:ee7d2910f5ea 156 if (data == ',') {
hideakitai 0:ee7d2910f5ea 157 state = kStateRssi;
hideakitai 0:ee7d2910f5ea 158 dcnt = cnt = 0;
hideakitai 0:ee7d2910f5ea 159 } else {
hideakitai 0:ee7d2910f5ea 160 pa.parent_id[cnt++] = data;
hideakitai 0:ee7d2910f5ea 161 }
hideakitai 0:ee7d2910f5ea 162 break;
hideakitai 0:ee7d2910f5ea 163 }
hideakitai 0:ee7d2910f5ea 164 case kStateRssi:
hideakitai 0:ee7d2910f5ea 165 {
hideakitai 0:ee7d2910f5ea 166 if (data == ':') {
hideakitai 0:ee7d2910f5ea 167 state = kStateData;
hideakitai 0:ee7d2910f5ea 168 dcnt = cnt = 0;
hideakitai 0:ee7d2910f5ea 169 } else {
hideakitai 0:ee7d2910f5ea 170 pa.rssi[cnt++] = data;
hideakitai 0:ee7d2910f5ea 171 }
hideakitai 0:ee7d2910f5ea 172 break;
hideakitai 0:ee7d2910f5ea 173 }
hideakitai 0:ee7d2910f5ea 174 case kStateData:
hideakitai 0:ee7d2910f5ea 175 {
hideakitai 0:ee7d2910f5ea 176 if (data == ',') {
hideakitai 0:ee7d2910f5ea 177 ++dcnt;
hideakitai 0:ee7d2910f5ea 178 cnt = 0;
hideakitai 0:ee7d2910f5ea 179 } else if (data == (char)kAsciiCR) {
hideakitai 0:ee7d2910f5ea 180 state = kStateCRLF;
hideakitai 0:ee7d2910f5ea 181 } else {
hideakitai 0:ee7d2910f5ea 182 pa.data[dcnt][cnt++] = data;
hideakitai 0:ee7d2910f5ea 183 }
hideakitai 0:ee7d2910f5ea 184 break;
hideakitai 0:ee7d2910f5ea 185 }
hideakitai 0:ee7d2910f5ea 186 case kStateCRLF:
hideakitai 0:ee7d2910f5ea 187 {
hideakitai 0:ee7d2910f5ea 188 if (data == (char)kAsciiLF)
hideakitai 0:ee7d2910f5ea 189 {
hideakitai 0:ee7d2910f5ea 190 Im920Packet p;
hideakitai 0:ee7d2910f5ea 191 p.node = (int)strtol(pa.node, NULL, 16);
hideakitai 0:ee7d2910f5ea 192 p.parent_id = (int)strtol(pa.parent_id, NULL, 16);
hideakitai 0:ee7d2910f5ea 193 p.rssi = (int)strtol(pa.rssi, NULL, 16);
hideakitai 0:ee7d2910f5ea 194 for (int i = 0; i < 8; i++) {
hideakitai 0:ee7d2910f5ea 195 p.data[i] = (int)strtol(pa.data[i], NULL, 16);
hideakitai 0:ee7d2910f5ea 196 }
hideakitai 0:ee7d2910f5ea 197 readBuffer_.push(p);
hideakitai 0:ee7d2910f5ea 198 // std::queue<int>().swap(q)
hideakitai 0:ee7d2910f5ea 199 }
hideakitai 0:ee7d2910f5ea 200 else
hideakitai 0:ee7d2910f5ea 201 {
hideakitai 0:ee7d2910f5ea 202 if(pc) pc->printf("invalid data order!!!\n");
hideakitai 0:ee7d2910f5ea 203 }
hideakitai 0:ee7d2910f5ea 204 state = kStateNode;
hideakitai 0:ee7d2910f5ea 205 bUnderParsing = false;
hideakitai 0:ee7d2910f5ea 206 dcnt = cnt = 0;
hideakitai 0:ee7d2910f5ea 207
hideakitai 0:ee7d2910f5ea 208 break;
hideakitai 0:ee7d2910f5ea 209 }
hideakitai 0:ee7d2910f5ea 210 default:
hideakitai 0:ee7d2910f5ea 211 {
hideakitai 0:ee7d2910f5ea 212 state = kStateNode;
hideakitai 0:ee7d2910f5ea 213 bUnderParsing = false;
hideakitai 0:ee7d2910f5ea 214 dcnt = cnt = 0;
hideakitai 0:ee7d2910f5ea 215 break;
hideakitai 0:ee7d2910f5ea 216 }
hideakitai 0:ee7d2910f5ea 217 }
hideakitai 0:ee7d2910f5ea 218 pop_byte();
hideakitai 0:ee7d2910f5ea 219 }
hideakitai 0:ee7d2910f5ea 220 }
hideakitai 0:ee7d2910f5ea 221
hideakitai 0:ee7d2910f5ea 222
hideakitai 0:ee7d2910f5ea 223 private:
hideakitai 0:ee7d2910f5ea 224 bool isCorrupted(int ascii)
hideakitai 0:ee7d2910f5ea 225 {
hideakitai 0:ee7d2910f5ea 226 bool isCRLF = ((ascii == 13) || (ascii == 10)) ? true : false;
hideakitai 0:ee7d2910f5ea 227 bool isPunctuation = ((ascii == 44) || (ascii == 58)) ? true : false;
hideakitai 0:ee7d2910f5ea 228 bool is0to9 = ((ascii >= 48) && (ascii <= 57)) ? true : false;
hideakitai 0:ee7d2910f5ea 229 bool isAtoF = ((ascii >= 65) && (ascii <= 70)) ? true : false;
hideakitai 0:ee7d2910f5ea 230 if (!(isCRLF || isPunctuation || is0to9 || isAtoF)) {
hideakitai 0:ee7d2910f5ea 231 if(pc) pc->printf("Invalid Ascii!\r\n");
hideakitai 0:ee7d2910f5ea 232 return true;
hideakitai 0:ee7d2910f5ea 233 }
hideakitai 0:ee7d2910f5ea 234 return false;
hideakitai 0:ee7d2910f5ea 235 }
hideakitai 0:ee7d2910f5ea 236
hideakitai 0:ee7d2910f5ea 237 queue<uint8_t> byte_buff;
hideakitai 0:ee7d2910f5ea 238 queue<Im920Packet> readBuffer_;
hideakitai 0:ee7d2910f5ea 239 Serial* pc;
hideakitai 0:ee7d2910f5ea 240 };
hideakitai 0:ee7d2910f5ea 241
hideakitai 0:ee7d2910f5ea 242