Cameron Reid
/
SmartThings_Switch
Mbed switch for Samsung SmartThings using Xbee
Main.cpp@2:e78ec8625034, 2016-09-15 (annotated)
- Committer:
- Cameron
- Date:
- Thu Sep 15 14:19:56 2016 +0000
- Revision:
- 2:e78ec8625034
- Parent:
- 1:80fe03be2832
V1
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Cameron | 0:1431a301c379 | 1 | #include "mbed.h" |
Cameron | 0:1431a301c379 | 2 | #include "C12832.h" |
Cameron | 0:1431a301c379 | 3 | |
Cameron | 0:1431a301c379 | 4 | #define AppV 0x01 |
Cameron | 0:1431a301c379 | 5 | #define HarV 0x01 |
Cameron | 0:1431a301c379 | 6 | |
Cameron | 0:1431a301c379 | 7 | C12832 lcd(p5, p7, p6, p8, p11); //configure LCD |
Cameron | 2:e78ec8625034 | 8 | RawSerial xbee(p9,p10); //Set Serial to XBee |
Cameron | 0:1431a301c379 | 9 | Serial pc(USBTX, USBRX); //Set Serial to PC. |
Cameron | 0:1431a301c379 | 10 | DigitalOut led2 (LED2); //configure onboard LEDs |
Cameron | 0:1431a301c379 | 11 | DigitalOut led1 (LED1); |
Cameron | 0:1431a301c379 | 12 | DigitalOut LED (LED4); |
Cameron | 0:1431a301c379 | 13 | volatile char x,y,z,len,sum; //some useful internal variables |
Cameron | 0:1431a301c379 | 14 | volatile int length, size, check; |
Cameron | 0:1431a301c379 | 15 | volatile int flag; |
Cameron | 0:1431a301c379 | 16 | char packet[60]; |
Cameron | 0:1431a301c379 | 17 | char PacketAddr[10]; |
Cameron | 0:1431a301c379 | 18 | char Opacket[60]; |
Cameron | 0:1431a301c379 | 19 | char AI[8] = {0x7E,0x00,0x04,0x08,0x21,0x41,0x49,0x4C}; //create AT command to querey network joined? |
Cameron | 0:1431a301c379 | 20 | char MY[8] = {0x7E,0x00,0x04,0x08,0x21,0x4D,0x59,0x30}; //create AT command to get my network ID. |
Cameron | 0:1431a301c379 | 21 | char SL[8] = {0x7E,0x00,0x04,0x08,0x21,0x53,0x4C,0x37}; //create AT command to get 64bit LSB. |
Cameron | 0:1431a301c379 | 22 | char SH[8] = {0x7E,0x00,0x04,0x08,0x21,0x53,0x48,0x3B}; //create AT command to get 64bit MSB. |
Cameron | 0:1431a301c379 | 23 | char CB[8] = {0x7E,0x00,0x04,0x08,0x21,0x43,0x42,0x51}; //Create AT command to leave network. |
Cameron | 0:1431a301c379 | 24 | char LNw[2]; |
Cameron | 0:1431a301c379 | 25 | char Addr[8]; |
Cameron | 0:1431a301c379 | 26 | char pay[101]; |
Cameron | 0:1431a301c379 | 27 | char Buffer[101]; |
Cameron | 0:1431a301c379 | 28 | char EP, DEP, SEP, seqNum, cmdID, frmType; |
Cameron | 0:1431a301c379 | 29 | char atID[2]; |
Cameron | 0:1431a301c379 | 30 | char Clu[2]; |
Cameron | 0:1431a301c379 | 31 | char Pro[2]; |
Cameron | 0:1431a301c379 | 32 | char Man[3] = {'A','R','M'}; //Product manufacturer |
Cameron | 0:1431a301c379 | 33 | char Dev[10] = {'N','X','P','L','P','C','1','7','6','8'}; //Device Name |
Cameron | 0:1431a301c379 | 34 | |
Cameron | 0:1431a301c379 | 35 | void packet_interupt(); //Create subroutine to deal with incoming packet. |
Cameron | 0:1431a301c379 | 36 | void Psend(char API_packet[]); //Create subroutine to send API commands |
Cameron | 0:1431a301c379 | 37 | void PBuild(char FrameAddr[], char sEP, char dEP, char Profile[], char Cluster[], char Payload[], char PaySize); //function to create packets to send. |
Cameron | 0:1431a301c379 | 38 | void Builder(); //Get usefull infromation from packets. |
Cameron | 0:1431a301c379 | 39 | void checksum(); //Create the checksum for the packet. |
Cameron | 0:1431a301c379 | 40 | void DevAnnc(); //function to send the device announce command. |
Cameron | 0:1431a301c379 | 41 | void SimpleDesc(); //Function to create the Simple description packet |
Cameron | 0:1431a301c379 | 42 | void ActiveEPReq(); //Function to create the Active end point request. |
Cameron | 0:1431a301c379 | 43 | void ClusterBasic(); //Function to create the Cluster Basic. |
Cameron | 0:1431a301c379 | 44 | void OnOff(); //Function to process on off commands. |
Cameron | 2:e78ec8625034 | 45 | void DefRes(); //Function to create the response for the on off command. |
Cameron | 2:e78ec8625034 | 46 | void Update(char val); |
Cameron | 0:1431a301c379 | 47 | |
Cameron | 0:1431a301c379 | 48 | int main(){ |
Cameron | 0:1431a301c379 | 49 | lcd.cls(); //clear lcd screen. |
Cameron | 0:1431a301c379 | 50 | lcd.locate(0,1); //locate the cursor. |
Cameron | 0:1431a301c379 | 51 | lcd.printf(" Joining network..."); //Print to lcd screen |
Cameron | 1:80fe03be2832 | 52 | memset(packet, 0, sizeof(packet)); //Clear array |
Cameron | 1:80fe03be2832 | 53 | |
Cameron | 1:80fe03be2832 | 54 | xbee.attach(&packet_interupt, Serial::RxIrq); //attach interupt when recieving serial information. |
Cameron | 0:1431a301c379 | 55 | |
Cameron | 0:1431a301c379 | 56 | while(packet[5] != 0){ //While Xbee has not joined a network |
Cameron | 0:1431a301c379 | 57 | wait(1); //Wait 0.1 second. |
Cameron | 0:1431a301c379 | 58 | Psend(AI); //Send network joined status again. |
Cameron | 1:80fe03be2832 | 59 | while(check == 0) |
Cameron | 2:e78ec8625034 | 60 | {} //Read data. |
Cameron | 0:1431a301c379 | 61 | } |
Cameron | 0:1431a301c379 | 62 | lcd.cls(); //Clear lcd screen. |
Cameron | 0:1431a301c379 | 63 | lcd.locate(0,1); //Locate the cursor. |
Cameron | 0:1431a301c379 | 64 | lcd.printf(" Connected"); //Print to lcd screen. |
Cameron | 0:1431a301c379 | 65 | |
Cameron | 1:80fe03be2832 | 66 | check = 0; |
Cameron | 0:1431a301c379 | 67 | Psend(MY); //Send AT command to get the 16bit network address. |
Cameron | 2:e78ec8625034 | 68 | while(check == 0) //Wait for packet. |
Cameron | 2:e78ec8625034 | 69 | {} |
Cameron | 2:e78ec8625034 | 70 | LNw[0] = packet[5]; //Transfer 16 bit address payload. |
Cameron | 2:e78ec8625034 | 71 | LNw[1] = packet[6]; //Transfer 16 bit address payload. |
Cameron | 0:1431a301c379 | 72 | |
Cameron | 0:1431a301c379 | 73 | check = 0; |
Cameron | 1:80fe03be2832 | 74 | Psend(SH); //Send AT command to get the 64bit address MSB. |
Cameron | 2:e78ec8625034 | 75 | while(check == 0) //Wait for packet. |
Cameron | 1:80fe03be2832 | 76 | {} |
Cameron | 0:1431a301c379 | 77 | Addr[0] = packet[5]; //Transfer 64 bit address payload. |
Cameron | 0:1431a301c379 | 78 | Addr[1] = packet[6]; //Transfer 64 bit address payload. |
Cameron | 0:1431a301c379 | 79 | Addr[2] = packet[7]; //Transfer 64 bit address payload. |
Cameron | 0:1431a301c379 | 80 | Addr[3] = packet[8]; //Transfer 64 bit address payload. |
Cameron | 0:1431a301c379 | 81 | |
Cameron | 0:1431a301c379 | 82 | check = 0; |
Cameron | 1:80fe03be2832 | 83 | Psend(SL); //Send AT command to get the 64bit address LSB. |
Cameron | 2:e78ec8625034 | 84 | while (check == 0) //Wait for packet. |
Cameron | 1:80fe03be2832 | 85 | {} |
Cameron | 2:e78ec8625034 | 86 | Addr[4] = packet[5]; //Transfer 64 bit address payload. |
Cameron | 2:e78ec8625034 | 87 | Addr[5] = packet[6]; //Transfer 64 bit address payload. |
Cameron | 2:e78ec8625034 | 88 | Addr[6] = packet[7]; //Transfer 64 bit address payload. |
Cameron | 2:e78ec8625034 | 89 | Addr[7] = packet[8]; //Transfer 64 bit address payload. |
Cameron | 0:1431a301c379 | 90 | DevAnnc(); //Send Device Announce. |
Cameron | 0:1431a301c379 | 91 | |
Cameron | 0:1431a301c379 | 92 | while(1) { |
Cameron | 2:e78ec8625034 | 93 | lcd.locate(0,21); //Locate LCD cursor. |
Cameron | 2:e78ec8625034 | 94 | lcd.printf("Packets recieved = %d", z); //Print to LCD display. |
Cameron | 2:e78ec8625034 | 95 | check = 0; |
Cameron | 2:e78ec8625034 | 96 | while(check == 0) //Wait for packet. |
Cameron | 2:e78ec8625034 | 97 | {} |
Cameron | 0:1431a301c379 | 98 | if (packet[16] == 0x00){ //If packet profile = 16. |
Cameron | 0:1431a301c379 | 99 | if (packet[14] == 0x04){ //If packet cluster = 14. |
Cameron | 0:1431a301c379 | 100 | lcd.locate(0,11); //Locate LCD cursor. |
Cameron | 0:1431a301c379 | 101 | lcd.printf(" simple dec"); |
Cameron | 0:1431a301c379 | 102 | SimpleDesc(); //Process Simple Desciption request. |
Cameron | 0:1431a301c379 | 103 | } |
Cameron | 0:1431a301c379 | 104 | else if (packet[14] ==0x05){ //If packet cluster = 15. |
Cameron | 0:1431a301c379 | 105 | lcd.locate(0,11); //Locate LCD display |
Cameron | 0:1431a301c379 | 106 | lcd.printf(" Active EP req"); |
Cameron | 0:1431a301c379 | 107 | ActiveEPReq(); //Process active EP Request. |
Cameron | 0:1431a301c379 | 108 | } |
Cameron | 0:1431a301c379 | 109 | else{ |
Cameron | 0:1431a301c379 | 110 | lcd.locate(0,11); //Locate LCD cursor. |
Cameron | 0:1431a301c379 | 111 | lcd.printf(" Unknown Packet"); //Print to lcd screen. |
Cameron | 0:1431a301c379 | 112 | } |
Cameron | 0:1431a301c379 | 113 | } |
Cameron | 0:1431a301c379 | 114 | else{ //Else if packet profile is not = 00. |
Cameron | 0:1431a301c379 | 115 | if (packet[14] == 0x00){ //If packet Cluster = 00. |
Cameron | 0:1431a301c379 | 116 | lcd.locate(0,11); //Locate LCD cursor. |
Cameron | 0:1431a301c379 | 117 | lcd.printf(" Cluster Basic"); |
Cameron | 0:1431a301c379 | 118 | ClusterBasic(); //Process Cluster Basic request. |
Cameron | 0:1431a301c379 | 119 | } |
Cameron | 0:1431a301c379 | 120 | else if (packet[14] ==0x06){ //Else if packet profile is not = 06. |
Cameron | 0:1431a301c379 | 121 | lcd.locate(0,11); //Locate LCD cursor. |
Cameron | 0:1431a301c379 | 122 | lcd.printf(" on/off "); |
Cameron | 0:1431a301c379 | 123 | OnOff(); //Process On/Off. |
Cameron | 0:1431a301c379 | 124 | } |
Cameron | 0:1431a301c379 | 125 | else{ |
Cameron | 0:1431a301c379 | 126 | lcd.locate(0,11); //Locate the cursor. |
Cameron | 0:1431a301c379 | 127 | lcd.printf(" Unknown Packet"); //Print to lcd screen. |
Cameron | 0:1431a301c379 | 128 | } |
Cameron | 0:1431a301c379 | 129 | } |
Cameron | 2:e78ec8625034 | 130 | } //end of while(1) |
Cameron | 0:1431a301c379 | 131 | } |
Cameron | 0:1431a301c379 | 132 | |
Cameron | 0:1431a301c379 | 133 | /********************************* Packet interupt *************************************** |
Cameron | 0:1431a301c379 | 134 | When a new Xbee packet is revieved it is sent to this function to be processed. |
Cameron | 0:1431a301c379 | 135 | |
Cameron | 0:1431a301c379 | 136 | *****************************************************************************************/ |
Cameron | 2:e78ec8625034 | 137 | void packet_interupt(){ //packet interupt begins when incoming data sensed on the rx line. |
Cameron | 2:e78ec8625034 | 138 | |
Cameron | 0:1431a301c379 | 139 | if (xbee.readable()) //If data is available |
Cameron | 0:1431a301c379 | 140 | x=xbee.getc(); //Get data |
Cameron | 0:1431a301c379 | 141 | if (x==0x7E){ //Test for start of Frame. |
Cameron | 2:e78ec8625034 | 142 | led2 = 1; //Set indicator LED2 to on. |
Cameron | 0:1431a301c379 | 143 | z ++; //Increment packet counter. |
Cameron | 0:1431a301c379 | 144 | memset(packet, 0, sizeof(packet)); //Clear packet buffer. |
Cameron | 0:1431a301c379 | 145 | while(xbee.readable() == 0); //If data is available. |
Cameron | 2:e78ec8625034 | 146 | x = xbee.getc(); //Get data MSB length. |
Cameron | 0:1431a301c379 | 147 | while(xbee.readable() == 0); //If data is available. |
Cameron | 2:e78ec8625034 | 148 | len = xbee.getc(); //Get data LSB length. |
Cameron | 2:e78ec8625034 | 149 | x = 0; //Counter to 0. |
Cameron | 0:1431a301c379 | 150 | sum = 0; //Set checksum calculator to 0. |
Cameron | 2:e78ec8625034 | 151 | while(x < (len + 1)){ //Fill packet variable with entire API packet. |
Cameron | 2:e78ec8625034 | 152 | while (xbee.readable() == 0); //If data is available. |
Cameron | 2:e78ec8625034 | 153 | packet[x] = xbee.getc(); //Get data and place it in the data array. |
Cameron | 0:1431a301c379 | 154 | sum = (sum + packet[x]); //Add value to checksum calculation. |
Cameron | 0:1431a301c379 | 155 | x++; |
Cameron | 0:1431a301c379 | 156 | } |
Cameron | 0:1431a301c379 | 157 | sum = (0xFF - ( sum & 0xFF)); //Finish calculating the checksum. |
Cameron | 2:e78ec8625034 | 158 | if (packet[x] == sum ){ //If the checksum and the calculated checksum are equal. |
Cameron | 0:1431a301c379 | 159 | if (packet[0] == 0x91){ //If packet ID = 0x91 |
Cameron | 0:1431a301c379 | 160 | Builder(); //Extract packet information |
Cameron | 0:1431a301c379 | 161 | check = 1; |
Cameron | 0:1431a301c379 | 162 | } |
Cameron | 1:80fe03be2832 | 163 | else if(packet[0] == 0x88){ //Else if packet ID = 0x88. |
Cameron | 0:1431a301c379 | 164 | check = 1; |
Cameron | 1:80fe03be2832 | 165 | } |
Cameron | 0:1431a301c379 | 166 | else |
Cameron | 0:1431a301c379 | 167 | memset(packet, 0, sizeof(packet)); //Clear array |
Cameron | 0:1431a301c379 | 168 | } |
Cameron | 0:1431a301c379 | 169 | else{ |
Cameron | 0:1431a301c379 | 170 | memset(packet, 0, sizeof(packet)); //Clear array |
Cameron | 0:1431a301c379 | 171 | } |
Cameron | 0:1431a301c379 | 172 | led2 = 0; //Set indicator LED2 to off. |
Cameron | 0:1431a301c379 | 173 | } |
Cameron | 0:1431a301c379 | 174 | } |
Cameron | 0:1431a301c379 | 175 | /************************************* Builder ****************************************** |
Cameron | 0:1431a301c379 | 176 | Extract all the important inforamtion from the packet and assoicate it to the relevant variable. |
Cameron | 0:1431a301c379 | 177 | *****************************************************************************************/ |
Cameron | 0:1431a301c379 | 178 | void Builder() |
Cameron | 0:1431a301c379 | 179 | { |
Cameron | 0:1431a301c379 | 180 | x = 0; //Set the counter to 0. |
Cameron | 0:1431a301c379 | 181 | while (x < 10){ //send the command |
Cameron | 0:1431a301c379 | 182 | PacketAddr[x] = packet[(x+1)]; //Copy the packets 16 and 64bit address. |
Cameron | 0:1431a301c379 | 183 | x ++; |
Cameron | 0:1431a301c379 | 184 | } |
Cameron | 0:1431a301c379 | 185 | DEP = packet[11]; //Get the source endpoint. |
Cameron | 0:1431a301c379 | 186 | SEP = packet[12]; //Get the destination endpoint. |
Cameron | 0:1431a301c379 | 187 | Clu[0] = packet[13]; //Get Cluster ID MSB. |
Cameron | 0:1431a301c379 | 188 | Clu[1] = packet[14]; //Get Cluster ID LSB. |
Cameron | 0:1431a301c379 | 189 | Pro[0] = packet[15]; //Get profile ID MSB. |
Cameron | 0:1431a301c379 | 190 | Pro[1] = packet[16]; //Get profile ID LSB. |
Cameron | 0:1431a301c379 | 191 | x = 0; //Set counter to 0. |
Cameron | 0:1431a301c379 | 192 | while ((x+18) < len){ |
Cameron | 0:1431a301c379 | 193 | pay[x] = packet[(x+18)]; //Copy packet payload. |
Cameron | 0:1431a301c379 | 194 | x++; |
Cameron | 0:1431a301c379 | 195 | } |
Cameron | 0:1431a301c379 | 196 | } |
Cameron | 0:1431a301c379 | 197 | /************************************ PBuild ****************************************** |
Cameron | 0:1431a301c379 | 198 | Organise the information from other functions into the correct packet format. |
Cameron | 0:1431a301c379 | 199 | |
Cameron | 0:1431a301c379 | 200 | *****************************************************************************************/ |
Cameron | 2:e78ec8625034 | 201 | void PBuild(char FrameAddr[], char sEP, char dEP, char Profile[], char Cluster[], char Payload[],char PaySize){ |
Cameron | 2:e78ec8625034 | 202 | |
Cameron | 0:1431a301c379 | 203 | size = 0; //Set size to 0. |
Cameron | 0:1431a301c379 | 204 | x = 0; //Set counter to 0. |
Cameron | 0:1431a301c379 | 205 | memset(Opacket, 0, sizeof(Opacket)); //Clear output buffer. |
Cameron | 0:1431a301c379 | 206 | |
Cameron | 0:1431a301c379 | 207 | size = 20 +(PaySize); //Find out the size of the out going packet. |
Cameron | 0:1431a301c379 | 208 | |
Cameron | 0:1431a301c379 | 209 | Opacket[0] = 0x7E; //Packet start bit. |
Cameron | 0:1431a301c379 | 210 | Opacket[1] = 0x00; //Packet length MSB. |
Cameron | 0:1431a301c379 | 211 | Opacket[2] = size; //Packet length LSB. |
Cameron | 0:1431a301c379 | 212 | Opacket[3] = 0x11; //Packet Type |
Cameron | 0:1431a301c379 | 213 | Opacket[4] = 0x00; //No response needed. |
Cameron | 0:1431a301c379 | 214 | Opacket[5] = FrameAddr[0]; //64 bit address High |
Cameron | 0:1431a301c379 | 215 | Opacket[6] = FrameAddr[1]; |
Cameron | 0:1431a301c379 | 216 | Opacket[7] = FrameAddr[2]; |
Cameron | 0:1431a301c379 | 217 | Opacket[8] = FrameAddr[3]; |
Cameron | 0:1431a301c379 | 218 | Opacket[9] = FrameAddr[4]; //64 bit address Low |
Cameron | 0:1431a301c379 | 219 | Opacket[10] = FrameAddr[5]; |
Cameron | 0:1431a301c379 | 220 | Opacket[11] = FrameAddr[6]; |
Cameron | 0:1431a301c379 | 221 | Opacket[12] = FrameAddr[7]; |
Cameron | 0:1431a301c379 | 222 | Opacket[13] = FrameAddr[8]; //16 bit PAN address |
Cameron | 0:1431a301c379 | 223 | Opacket[14] = FrameAddr[9]; |
Cameron | 0:1431a301c379 | 224 | Opacket[15] = sEP; //Source Endpoint |
Cameron | 0:1431a301c379 | 225 | Opacket[16] = dEP; //Destinaton Endpoint |
Cameron | 0:1431a301c379 | 226 | Opacket[17] = Cluster[0]; //Cluster ID |
Cameron | 0:1431a301c379 | 227 | Opacket[18] = Cluster[1]; |
Cameron | 0:1431a301c379 | 228 | Opacket[19] = Profile[0]; //Profile ID |
Cameron | 0:1431a301c379 | 229 | Opacket[20] = Profile[1]; |
Cameron | 0:1431a301c379 | 230 | Opacket[21] = 0x00; //Broadcast radius |
Cameron | 0:1431a301c379 | 231 | Opacket[22] = 0x00; //Trasmit option bitfield |
Cameron | 0:1431a301c379 | 232 | while (x < PaySize){ |
Cameron | 0:1431a301c379 | 233 | Opacket[(23 + x)] = Payload[x]; //Copy packet payload |
Cameron | 0:1431a301c379 | 234 | x ++; |
Cameron | 0:1431a301c379 | 235 | } |
Cameron | 0:1431a301c379 | 236 | |
Cameron | 0:1431a301c379 | 237 | checksum(); //Create the check sum. |
Cameron | 0:1431a301c379 | 238 | Psend(Opacket); //Send the packet. |
Cameron | 0:1431a301c379 | 239 | } |
Cameron | 0:1431a301c379 | 240 | /************************************ Checksum ****************************************** |
Cameron | 0:1431a301c379 | 241 | Create the checksum for outgoing packets. |
Cameron | 0:1431a301c379 | 242 | |
Cameron | 0:1431a301c379 | 243 | *****************************************************************************************/ |
Cameron | 2:e78ec8625034 | 244 | void checksum(){ |
Cameron | 2:e78ec8625034 | 245 | |
Cameron | 0:1431a301c379 | 246 | y = 0; //Set Alternatie counter to 0 |
Cameron | 0:1431a301c379 | 247 | sum = 0; |
Cameron | 0:1431a301c379 | 248 | while (y < (Opacket[2])){ //Create the checksum. |
Cameron | 0:1431a301c379 | 249 | sum = (sum + Opacket[y + 3]); |
Cameron | 0:1431a301c379 | 250 | y++; |
Cameron | 0:1431a301c379 | 251 | } |
Cameron | 0:1431a301c379 | 252 | Opacket[23 + x] = (0xFF - ( sum & 0xFF)); |
Cameron | 0:1431a301c379 | 253 | } |
Cameron | 0:1431a301c379 | 254 | /************************************* Psend ******************************************** |
Cameron | 0:1431a301c379 | 255 | Send the packet out serially to the Xbee module. |
Cameron | 0:1431a301c379 | 256 | |
Cameron | 0:1431a301c379 | 257 | *****************************************************************************************/ |
Cameron | 2:e78ec8625034 | 258 | void Psend(char API_packet[]){ |
Cameron | 2:e78ec8625034 | 259 | |
Cameron | 0:1431a301c379 | 260 | led1 = 1; //Set onboard LED1 on for diagnostics |
Cameron | 0:1431a301c379 | 261 | length = (API_packet[2] + 4); //Calaculate packet length using packet length identifier and add the start byte, 2 byte length and checksum. |
Cameron | 0:1431a301c379 | 262 | x = 0; |
Cameron | 0:1431a301c379 | 263 | while (x < length){ //Send the command |
Cameron | 0:1431a301c379 | 264 | xbee.putc(API_packet[x]); |
Cameron | 0:1431a301c379 | 265 | x ++; |
Cameron | 0:1431a301c379 | 266 | } |
Cameron | 0:1431a301c379 | 267 | led1 = 0; //Set diagnostics LED1 to off |
Cameron | 0:1431a301c379 | 268 | } |
Cameron | 0:1431a301c379 | 269 | /********************************* Device Announce ************************************** |
Cameron | 0:1431a301c379 | 270 | Send a Device announce packet when joining or re joining and network. |
Cameron | 0:1431a301c379 | 271 | For more informaion see ZigBee spec page 109 |
Cameron | 0:1431a301c379 | 272 | *****************************************************************************************/ |
Cameron | 2:e78ec8625034 | 273 | void DevAnnc(){ |
Cameron | 2:e78ec8625034 | 274 | |
Cameron | 0:1431a301c379 | 275 | char AnncFrame[16] = {0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFE}; |
Cameron | 0:1431a301c379 | 276 | char AnncPayload[12]; //Create char array for payload. |
Cameron | 0:1431a301c379 | 277 | char DevClu[2] = {0x00, 0x13}; //Create char array for Cluster ID. |
Cameron | 0:1431a301c379 | 278 | char DevPro[2] = {0x00, 0x00}; //Create char array for Profile ID. |
Cameron | 0:1431a301c379 | 279 | AnncPayload[0] = 0x22; //Set seqence ID to 0x22. |
Cameron | 0:1431a301c379 | 280 | AnncPayload[1] = LNw[1]; //Copy 16bit PAN address little endian. |
Cameron | 0:1431a301c379 | 281 | AnncPayload[2] = LNw[0]; |
Cameron | 0:1431a301c379 | 282 | AnncPayload[3] = Addr[7]; //Copy 64bit address little endian. |
Cameron | 0:1431a301c379 | 283 | AnncPayload[4] = Addr[6]; |
Cameron | 0:1431a301c379 | 284 | AnncPayload[5] = Addr[5]; |
Cameron | 0:1431a301c379 | 285 | AnncPayload[6] = Addr[4]; |
Cameron | 0:1431a301c379 | 286 | AnncPayload[7] = Addr[3]; |
Cameron | 0:1431a301c379 | 287 | AnncPayload[8] = Addr[2]; |
Cameron | 0:1431a301c379 | 288 | AnncPayload[9] = Addr[1]; |
Cameron | 0:1431a301c379 | 289 | AnncPayload[10] = Addr[0]; |
Cameron | 0:1431a301c379 | 290 | AnncPayload[11] = 0x8C; //Set device parameters. |
Cameron | 0:1431a301c379 | 291 | |
Cameron | 0:1431a301c379 | 292 | PBuild(AnncFrame,0x00,0x00,DevPro,DevClu, AnncPayload, 12); //Send packet to builder. |
Cameron | 0:1431a301c379 | 293 | } |
Cameron | 0:1431a301c379 | 294 | /******************************** Simple Description ************************************ |
Cameron | 0:1431a301c379 | 295 | Send a response to a Simple Description Request. |
Cameron | 0:1431a301c379 | 296 | For more informaion see ZigBee spec page 159. |
Cameron | 0:1431a301c379 | 297 | *****************************************************************************************/ |
Cameron | 2:e78ec8625034 | 298 | void SimpleDesc(){ |
Cameron | 2:e78ec8625034 | 299 | |
Cameron | 0:1431a301c379 | 300 | EP = pay[3]; //Get endpoint from payload. |
Cameron | 0:1431a301c379 | 301 | char DescClu[2] = {0x80,0x04}; //Create char array for cluster ID. |
Cameron | 0:1431a301c379 | 302 | char DescPro[2] = {0x00,0x00}; //Create char array for profile ID. |
Cameron | 0:1431a301c379 | 303 | |
Cameron | 0:1431a301c379 | 304 | if( EP == 0x76){ //If Endpoint = 38. |
Cameron | 0:1431a301c379 | 305 | memset(Buffer, 0, sizeof(Buffer)); //Clear array |
Cameron | 0:1431a301c379 | 306 | Buffer[0] = pay[0]; //Set Transcation Seq number to match inbound packets seq number |
Cameron | 0:1431a301c379 | 307 | Buffer[1] = 0x00; //Status $00 = success Table 2.93 on page 159 of ZBSpec |
Cameron | 0:1431a301c379 | 308 | Buffer[2] = pay[1]; //Set Network address little endian order |
Cameron | 0:1431a301c379 | 309 | Buffer[3] = pay[2]; |
Cameron | 0:1431a301c379 | 310 | Buffer[4] = 0x0E; //Length in bytes of the Simple Descriptor to Follow |
Cameron | 0:1431a301c379 | 311 | Buffer[5] = 0x76; //Endpoint of the simple descriptor Table 2.38 on page 88 of ZBSpec |
Cameron | 0:1431a301c379 | 312 | Buffer[6] = 0x04; //Application Profile ID 2 Bytes Little endian. $0104 = Home Automation Profile |
Cameron | 0:1431a301c379 | 313 | Buffer[7] = 0x01; |
Cameron | 0:1431a301c379 | 314 | Buffer[8] = 0x02; //Device type 2 Bytes Little endian, $0002 = On/Off Output see page 42 of ZigBee Home Automation Profile |
Cameron | 0:1431a301c379 | 315 | Buffer[9] = 0x00; |
Cameron | 0:1431a301c379 | 316 | Buffer[10] = 0x00; //App Dev Version 4bits + reserved 4bits |
Cameron | 0:1431a301c379 | 317 | Buffer[11] = 0x02; //Input cluster count in this case we only have $02 input clusters |
Cameron | 0:1431a301c379 | 318 | Buffer[12] = 0x00; //Input cluster list 2 bytes each little endian. $0000 = Basic Cluster |
Cameron | 0:1431a301c379 | 319 | Buffer[13] = 0x00; |
Cameron | 0:1431a301c379 | 320 | Buffer[14] = 0x06; //Output cluster 2 bytes each little endian. $0006 = On / Off Cluster |
Cameron | 0:1431a301c379 | 321 | Buffer[15] = 0x00; |
Cameron | 0:1431a301c379 | 322 | Buffer[16] = 0x00; //Output cluster list. No output cluster. |
Cameron | 0:1431a301c379 | 323 | PBuild(PacketAddr,0x00,0x00,DescPro,DescClu, Buffer, 0x11); |
Cameron | 0:1431a301c379 | 324 | } |
Cameron | 0:1431a301c379 | 325 | |
Cameron | 0:1431a301c379 | 326 | else{ |
Cameron | 0:1431a301c379 | 327 | memset(Buffer, 0, sizeof(Buffer)); //Clear array. |
Cameron | 0:1431a301c379 | 328 | Buffer[0] = pay[0]; //Set Transcation Seq number to match inbound packets seq number. |
Cameron | 0:1431a301c379 | 329 | Buffer[1] = 0x82; //Status $82 = Invalid_EP page 212 of ZigBee Specification. |
Cameron | 0:1431a301c379 | 330 | Buffer[2] = pay[1]; //Set Network address little endian order. |
Cameron | 0:1431a301c379 | 331 | Buffer[3] = pay[2]; |
Cameron | 0:1431a301c379 | 332 | Buffer[4] = 0x00; //Length in bytes of simple descriptor to follow. |
Cameron | 0:1431a301c379 | 333 | PBuild(PacketAddr,0x00,0x00,DescPro,DescClu, Buffer, 0x05); |
Cameron | 0:1431a301c379 | 334 | } |
Cameron | 0:1431a301c379 | 335 | } |
Cameron | 0:1431a301c379 | 336 | /******************************** Active EP Request ************************************ |
Cameron | 0:1431a301c379 | 337 | Send a response to and Active EP Request. |
Cameron | 0:1431a301c379 | 338 | For more informaion see ZigBee spec page 161. |
Cameron | 0:1431a301c379 | 339 | *****************************************************************************************/ |
Cameron | 2:e78ec8625034 | 340 | void ActiveEPReq(){ |
Cameron | 2:e78ec8625034 | 341 | |
Cameron | 0:1431a301c379 | 342 | char EPReqClu[2] = {0x80, 0x05}; //Create char array for Cluster. |
Cameron | 0:1431a301c379 | 343 | char EPReqPro[2] = {0x00, 0x00}; //Create char array for Profile. |
Cameron | 0:1431a301c379 | 344 | memset(Buffer, 0, sizeof(Buffer)); //Clear array. |
Cameron | 0:1431a301c379 | 345 | Buffer[0] = pay[0]; //Set Transcation Seq number to match inbound packets seq number. |
Cameron | 0:1431a301c379 | 346 | Buffer[1] = 0x00; //Status $00 = success Table 2.93 on page 159 of ZBSpec. |
Cameron | 0:1431a301c379 | 347 | Buffer[2] = pay[1]; //Set Network address little endian order. |
Cameron | 0:1431a301c379 | 348 | Buffer[3] = pay[2]; |
Cameron | 0:1431a301c379 | 349 | Buffer[4] = 0x01; //Active end point count in this case 1. |
Cameron | 0:1431a301c379 | 350 | Buffer[5] = 0x76; //Endpoint 38. |
Cameron | 0:1431a301c379 | 351 | PBuild(PacketAddr,0x00,0x00,EPReqPro,EPReqClu, Buffer, 0x06); |
Cameron | 0:1431a301c379 | 352 | } |
Cameron | 0:1431a301c379 | 353 | /********************************** Cluster Basic *************************************** |
Cameron | 0:1431a301c379 | 354 | Process a Basic Cluster request. |
Cameron | 0:1431a301c379 | 355 | For more informaion see ZigBee cluster library page 78 |
Cameron | 0:1431a301c379 | 356 | *****************************************************************************************/ |
Cameron | 2:e78ec8625034 | 357 | void ClusterBasic(){ |
Cameron | 2:e78ec8625034 | 358 | |
Cameron | 0:1431a301c379 | 359 | cmdID = 0; //Set command ID to 0. |
Cameron | 0:1431a301c379 | 360 | seqNum = 0; //Set seqence number to 0. |
Cameron | 0:1431a301c379 | 361 | memset(Buffer, 0, sizeof(Buffer)); //Clear array. |
Cameron | 0:1431a301c379 | 362 | memset(atID, 0, sizeof(atID)); //Clear array. |
Cameron | 0:1431a301c379 | 363 | |
Cameron | 0:1431a301c379 | 364 | seqNum = pay[1]; //Copy seqence number from payload. |
Cameron | 0:1431a301c379 | 365 | cmdID = pay[2]; //Copy command ID from payload. |
Cameron | 0:1431a301c379 | 366 | atID[0] = pay[3]; //Copy attribute ID LSB from payload. |
Cameron | 0:1431a301c379 | 367 | atID[1] = pay[4]; //Copy attribute ID MSB from payload. |
Cameron | 0:1431a301c379 | 368 | |
Cameron | 0:1431a301c379 | 369 | if ((cmdID == 0x00) && (atID[0] == 0x01) && (atID[1] == 0x00)){ //If Application version is requested. |
Cameron | 0:1431a301c379 | 370 | Buffer[0] = 0x18; //Frame control direction is server to client. |
Cameron | 0:1431a301c379 | 371 | Buffer[1] = seqNum; //Reply with seqence number from request. |
Cameron | 0:1431a301c379 | 372 | Buffer[2] = 0x01; //Command indetifier = 1, Read attribute response. |
Cameron | 0:1431a301c379 | 373 | Buffer[3] = 0x01; //Attribute Identfier (2 bytes) field being reported. |
Cameron | 0:1431a301c379 | 374 | Buffer[4] = 0x00; |
Cameron | 0:1431a301c379 | 375 | Buffer[5] = 0x00; //status 00 success. |
Cameron | 0:1431a301c379 | 376 | Buffer[6] = 0x20; //Attribute data type 0x20 = unsigned 8 bit integer. |
Cameron | 0:1431a301c379 | 377 | Buffer[7] = AppV; //Application version. |
Cameron | 0:1431a301c379 | 378 | PBuild(PacketAddr,SEP,DEP,Pro,Clu, Buffer, 0x08); //Send data to packet builder. |
Cameron | 0:1431a301c379 | 379 | } |
Cameron | 0:1431a301c379 | 380 | |
Cameron | 0:1431a301c379 | 381 | if ((cmdID == 0x00) && (atID[0] == 0x03) && (atID[1] == 0x00)){ //If Hardware version is requeted. |
Cameron | 0:1431a301c379 | 382 | Buffer[0] = 0x18; //Frame control direction is server to client. |
Cameron | 0:1431a301c379 | 383 | Buffer[1] = seqNum; //Reply with seqence number from request. |
Cameron | 0:1431a301c379 | 384 | Buffer[2] = 0x01; //Command indetifier = 1, Read attribute response. |
Cameron | 0:1431a301c379 | 385 | Buffer[3] = 0x03; //Attribute Identfier (2 bytes) field being reported. |
Cameron | 0:1431a301c379 | 386 | Buffer[4] = 0x00; |
Cameron | 0:1431a301c379 | 387 | Buffer[5] = 0x00; //status 00 success. |
Cameron | 0:1431a301c379 | 388 | Buffer[6] = 0x20; //Attribute data type 0x20 = unsigned 8 bit integer. |
Cameron | 0:1431a301c379 | 389 | Buffer[7] = HarV; //Hardware version. |
Cameron | 0:1431a301c379 | 390 | PBuild(PacketAddr,SEP,DEP,Pro,Clu, Buffer, 0x08); //Send data to packet builder. |
Cameron | 0:1431a301c379 | 391 | } |
Cameron | 0:1431a301c379 | 392 | |
Cameron | 0:1431a301c379 | 393 | if ((cmdID == 0x00) && (atID[0] == 0x04) && (atID[1] == 0x00)){ //If device Manufacturer is requested |
Cameron | 0:1431a301c379 | 394 | Buffer[0] = 0x18; //Frame control direction is server to client. |
Cameron | 0:1431a301c379 | 395 | Buffer[1] = seqNum; //Reply with seqence number from request. |
Cameron | 0:1431a301c379 | 396 | Buffer[2] = 0x01; //Command indetifier = 1, Read attribute response. |
Cameron | 0:1431a301c379 | 397 | Buffer[3] = 0x04; //Attribute Identfier (2 bytes) field being reported. |
Cameron | 0:1431a301c379 | 398 | Buffer[4] = 0x00; |
Cameron | 0:1431a301c379 | 399 | Buffer[5] = 0x00; //status 00 success. |
Cameron | 0:1431a301c379 | 400 | Buffer[6] = 0x42; //Attribute data type 0x42 = character string. |
Cameron | 0:1431a301c379 | 401 | Buffer[7] = sizeof(Man); //Size of string to follow. |
Cameron | 0:1431a301c379 | 402 | x = 0; |
Cameron | 0:1431a301c379 | 403 | while( x < (sizeof(Man))){ //Send sting byte by byte. |
Cameron | 0:1431a301c379 | 404 | Buffer[(x+8)] = Man[x]; |
Cameron | 0:1431a301c379 | 405 | x++; |
Cameron | 0:1431a301c379 | 406 | } |
Cameron | 0:1431a301c379 | 407 | PBuild(PacketAddr,SEP,DEP,Pro,Clu, Buffer, (0x08 + Buffer[7])); //Send data to packet builder. |
Cameron | 0:1431a301c379 | 408 | } |
Cameron | 0:1431a301c379 | 409 | |
Cameron | 0:1431a301c379 | 410 | if ((cmdID == 0x00) && (atID[0] == 0x05) && (atID[1] == 0x00)){ //If Device devoloper is requested. |
Cameron | 0:1431a301c379 | 411 | Buffer[0] = 0x18; //Frame control direction is server to client. |
Cameron | 0:1431a301c379 | 412 | Buffer[1] = seqNum; //Reply with seqence number from request. |
Cameron | 0:1431a301c379 | 413 | Buffer[2] = 0x01; //Command indetifier = 1, Read attribute response. |
Cameron | 0:1431a301c379 | 414 | Buffer[3] = 0x05; //Attribute Identfier (2 bytes) field being reported. |
Cameron | 0:1431a301c379 | 415 | Buffer[4] = 0x00; |
Cameron | 0:1431a301c379 | 416 | Buffer[5] = 0x00; //status 00 success. |
Cameron | 0:1431a301c379 | 417 | Buffer[6] = 0x42; //Attribute data type 0x42 = character string. |
Cameron | 0:1431a301c379 | 418 | Buffer[7] = sizeof(Dev) ; //Size of string to follow. |
Cameron | 0:1431a301c379 | 419 | x = 0; |
Cameron | 0:1431a301c379 | 420 | while( x < (sizeof(Dev))){ //Send sting byte by byte. |
Cameron | 0:1431a301c379 | 421 | Buffer[(x+8)] = Dev[x]; |
Cameron | 0:1431a301c379 | 422 | x++; |
Cameron | 0:1431a301c379 | 423 | } |
Cameron | 0:1431a301c379 | 424 | PBuild(PacketAddr,SEP,DEP,Pro,Clu, Buffer, (0x08 + Buffer[7])); //Send data to packet builder. |
Cameron | 0:1431a301c379 | 425 | } |
Cameron | 0:1431a301c379 | 426 | } |
Cameron | 0:1431a301c379 | 427 | /******************************** Switch Cluster ************************************ |
Cameron | 0:1431a301c379 | 428 | Process and respond to a Switch cluster command. |
Cameron | 0:1431a301c379 | 429 | For more informaion see ZigBee Cluster library page 125. |
Cameron | 0:1431a301c379 | 430 | *****************************************************************************************/ |
Cameron | 2:e78ec8625034 | 431 | void OnOff(){ |
Cameron | 0:1431a301c379 | 432 | cmdID = 0; //Set command ID to 0. |
Cameron | 0:1431a301c379 | 433 | seqNum = 0; //Set seqence number to 0. |
Cameron | 0:1431a301c379 | 434 | frmType = 0; //Set frame type to 0. |
Cameron | 0:1431a301c379 | 435 | memset(Buffer, 0, sizeof(Buffer)); //Clear array |
Cameron | 0:1431a301c379 | 436 | memset(atID, 0, sizeof(atID)); //Clear array |
Cameron | 0:1431a301c379 | 437 | |
Cameron | 0:1431a301c379 | 438 | frmType = pay[0]; //Get frame type from payload. |
Cameron | 0:1431a301c379 | 439 | frmType = frmType & 0x03; //Bitwise & with 0x03 to make sure you are looking at the first 2 bits. |
Cameron | 0:1431a301c379 | 440 | seqNum = pay[1]; //Get Seqence Number for payload. |
Cameron | 0:1431a301c379 | 441 | cmdID = pay[2]; //Get command ID from payload. |
Cameron | 0:1431a301c379 | 442 | atID[0] = pay[3]; //Get attribute ID MSB. |
Cameron | 0:1431a301c379 | 443 | atID[1] = pay[4]; //Get attribute ID LSB. |
Cameron | 0:1431a301c379 | 444 | |
Cameron | 0:1431a301c379 | 445 | if ((frmType == 0x00) && (cmdID == 0x00) && (atID[1] == 0x00)){ //If Command to check status is sent. |
Cameron | 2:e78ec8625034 | 446 | Update(LED); |
Cameron | 0:1431a301c379 | 447 | } |
Cameron | 0:1431a301c379 | 448 | |
Cameron | 0:1431a301c379 | 449 | if ((frmType == 0x01) && (cmdID == 0x00) && (atID[1] == 0x00)){ //command to turn off LED. |
Cameron | 0:1431a301c379 | 450 | LED = 0; //Turn LED off. |
Cameron | 2:e78ec8625034 | 451 | DefRes(); |
Cameron | 0:1431a301c379 | 452 | } |
Cameron | 0:1431a301c379 | 453 | |
Cameron | 0:1431a301c379 | 454 | if ((frmType == 0x01) && (cmdID == 0x01) && (atID[1] == 0x00)){ //Command to turn on LED. |
Cameron | 0:1431a301c379 | 455 | LED = 1; //Turn LED on. |
Cameron | 2:e78ec8625034 | 456 | DefRes(); //Create response. |
Cameron | 0:1431a301c379 | 457 | } |
Cameron | 2:e78ec8625034 | 458 | |
Cameron | 0:1431a301c379 | 459 | if ((frmType == 0x01) && (cmdID == 0x02) && (atID[1] == 0x00)){ //Command to toggle LED. |
Cameron | 0:1431a301c379 | 460 | LED = !LED; //Toggle LED |
Cameron | 2:e78ec8625034 | 461 | DefRes(); |
Cameron | 0:1431a301c379 | 462 | } |
Cameron | 0:1431a301c379 | 463 | } |
Cameron | 0:1431a301c379 | 464 | /********************************* Default Response ************************************* |
Cameron | 0:1431a301c379 | 465 | Create a default response. |
Cameron | 0:1431a301c379 | 466 | |
Cameron | 0:1431a301c379 | 467 | *****************************************************************************************/ |
Cameron | 2:e78ec8625034 | 468 | void DefRes(){ |
Cameron | 2:e78ec8625034 | 469 | |
Cameron | 0:1431a301c379 | 470 | Buffer[0] = 0x18; //Frame control direction is server to client. |
Cameron | 0:1431a301c379 | 471 | Buffer[1] = seqNum; //Reply with seqence number from request. |
Cameron | 0:1431a301c379 | 472 | Buffer[2] = 0x0B; //Command identifier 0x08 = default response. |
Cameron | 0:1431a301c379 | 473 | Buffer[3] = cmdID; //reply with the command ID sne to you. |
Cameron | 2:e78ec8625034 | 474 | Buffer[4] = 0x00; //Send sucess 00 |
Cameron | 2:e78ec8625034 | 475 | PBuild(PacketAddr,SEP,DEP,Pro,Clu, Buffer, 0x05); //Send to packet builder. |
Cameron | 2:e78ec8625034 | 476 | } |
Cameron | 2:e78ec8625034 | 477 | /************************************** Update ****************************************** |
Cameron | 2:e78ec8625034 | 478 | Update LEDs status. |
Cameron | 2:e78ec8625034 | 479 | |
Cameron | 2:e78ec8625034 | 480 | *****************************************************************************************/ |
Cameron | 2:e78ec8625034 | 481 | void Update(char val){ |
Cameron | 2:e78ec8625034 | 482 | |
Cameron | 2:e78ec8625034 | 483 | Buffer[0] = 0x18; //Frame control direction is server to client. |
Cameron | 2:e78ec8625034 | 484 | Buffer[1] = seqNum; //Reply with seqence number from request. |
Cameron | 2:e78ec8625034 | 485 | Buffer[2] = 0x01; //Command indetifier = 1, Read attribute response. |
Cameron | 2:e78ec8625034 | 486 | Buffer[3] = 0x00; //Attribute Identfier (2 bytes) field being reported. |
Cameron | 2:e78ec8625034 | 487 | Buffer[4] = 0x00; |
Cameron | 2:e78ec8625034 | 488 | Buffer[5] = 0x00; //Status 00 = success. |
Cameron | 2:e78ec8625034 | 489 | Buffer[6] = 0x10; //Attribute data type 10 = boolean. |
Cameron | 2:e78ec8625034 | 490 | Buffer[7] = val; //Read LED state. |
Cameron | 2:e78ec8625034 | 491 | PBuild(PacketAddr,SEP,DEP,Pro,Clu, Buffer, 0x08); //Send to packet builder. |
Cameron | 0:1431a301c379 | 492 | } |