A libery to connect to telegesis zigbee module. Bassed on implemtation of XBEE
Fork of xbee_lib by
telegesis.cpp
- Committer:
- gert_lauritsen
- Date:
- 2014-11-28
- Revision:
- 31:c59bc92a047e
- Parent:
- 30:f9cdb6f62586
- Child:
- 32:e44448cee1e1
File content as of revision 31:c59bc92a047e:
#include "telegesis.h" #define CR 0x0D #define LF 0x0A //#define IRQCtrl zigbee::zigbee(PinName tx, PinName rx): _zbee(tx, rx) { _tx = tx; _rx = rx; _zbee.baud(19200); Ok=1; PacketAck=1; #ifdef IRQCtrl _zbee.attach(this, &zigbee::SeePacket, Serial::RxIrq); #endif } size_t zigbee::comma_parse ( char *line, char *list[], size_t size ) { char *p; size_t n; p = line; n = 0; for ( ; ; ) { /* Ditch leading commas */ while ( *p == ',' ) p++; /* Nothing of use */ if ( *p == '\0' ) return n; /* Save the string */ list[n++] = p; /* Find the next field */ while ( *p != ',' && *p != '\0' ) p++; /* Nothing else of use or too many fields */ if ( *p == '\0' || n >= size ) return n; /* Split the field */ *p++ = '\0'; } } zigbee::~zigbee() { } bool zigbee::Work() { //read and waits for the packet bool datain=false; b=0; if (_zbee.readable()) { datain=true; SeePacket(); } return datain; } bool zigbee::wait4str(char *p) //joinpan { Timer t; t.reset(); t.start(); while ((strstr(_responseFrameString,p)==0) && (t.read_ms() < 5000)) readPacket(); t.stop(); return (strstr(_responseFrameString,p)>0); } bool zigbee::wait4JPAN() //joinpan { Timer t; t.reset(); t.start(); readPacket(); while ((strstr(_responseFrameString,"JPAN")==0) && (t.read_ms() < 5000)) readPacket(); t.stop(); return (strstr(_responseFrameString,"JPAN")>0); } bool zigbee::wait4Offline() { Timer t; t.reset(); t.start(); readPacket(); while ((PanOnline>0) && (t.read_ms() < 3000)) readPacket(); t.stop(); return PanOnline; } bool zigbee::wait4OK() { Timer t; t.reset(); t.start(); readPacket(); while ((strstr(_responseFrameString,"OK")==0) && (t.read_ms() < 500)) readPacket(); t.stop(); return (strstr(_responseFrameString,"OK")>0); } int zigbee::GetSerial() { /** comes with something like this Telegesis ETRX357-LRS R305C 000D6F0000D5F06A OK */ _zbee.printf("ATI\r"); wait4str("Telegesis"); sscanf(_responseFrameString,"Telegesis %s",HWType); readPacket(); //Typen readPacket(); //ID strcpy(LocalID,_responseFrameString); //vi lægger den bare over i stringformat. Så kan man altid senere convertere wait4OK(); // LocalID=hextoint(_responseFrameString); // wait_ms(5); return 1; } int zigbee::SetKey(char* key) { /** S09: the link key. Write the same 128-bit number (32 hexadecimal characters) into every device S0A: security configuration. You must set bit 4 in the coordinator, and set bit 8 in all other devices. For more security set bit 2 also in the coordinator. The devices ignore the bits that are not relevant for them, so it is easiest to just set bits 8, 4, and 2 in all devices which gives S0A=0114. */ char psw[50]; sprintf(psw,"ATS09=%s;password\r",key); _zbee.printf(psw); wait4OK(); _zbee.printf("ATS0A=0114;password\r"); return 1; } void zigbee::RecieveData(char *data_buf, int numchar) { int count=0; if(numchar == 0) { numchar = sizeof(data_buf); } while(numchar!=count) { if(_zbee.readable()) { *data_buf = _zbee.getc(); data_buf+=1; count++; } } } int zigbee::Reset() { PacketAck=0; _zbee.printf("ATZ\r"); wait4OK(); return 1; } int zigbee::ATI() { PacketAck=0; GetSerial(); return 1; } int zigbee::PingOut() { //just return a OK (sends it ID out out the pan) PacketAck=0; _zbee.printf("AT+ANNCE\r"); wait4OK(); return 1; } int zigbee::PanScan() { // PacketAck=0; NPanVisible=0; _zbee.printf("AT+PANSCAN\r"); wait4OK(); return 1; } int zigbee::Establish_Network() { // PacketAck=0; _zbee.printf("AT+EN\r"); wait4JPAN(); wait4OK(); return 1; } int zigbee::LeaveNetwork() { PacketAck=0; _zbee.printf("AT+DASSL\r"); wait4OK(); wait4Offline(); return 1; } int zigbee::JoinNetwork() { PacketAck=0; _zbee.printf("AT+JN\r"); Ok=0; return 1; } int zigbee::ScanNetwork() { PacketAck=0; _zbee.printf("AT+SN\r"); Ok=0; return 1; } int zigbee::NetworkInfo() { //Return something like this "+N=COO,12,-11,29F0,55C0E0DCE605C522" PacketAck=0; _zbee.printf("AT+N\r"); Ok=wait4OK(); return 1; } int zigbee::UniCast(char *adr,char *payload) //Ascii mode with null terminated string { PacketAck=0; _zbee.printf("AT+UCAST:%s=%s\r",adr,payload); // printf("AT+UCAST:%s=%s\r",adr,payload); // _zbee.scanf ("UCAST:%X,%X=%s ",&EUI64,&framesize,Zdata); Ok=0; return 1; } int zigbee::UniCastb(char *adr,char *payload, char payloadSize) //sends data in binary format { PacketAck=0; _zbee.printf("AT+UCASTB:%X,%s\r",adr,payloadSize); //_zbee.scanf ("%*s"); return 1; } //-----------------------Handle incoming data------------------------------ unsigned long zigbee::hextolong(const char *hex) { //return 32 bit unsigned long result = 0; while (*hex) { //så længe det ikke er null if (*hex >= '0' && *hex <= '9') result += (*hex - '0'); else if (*hex >= 'A' && *hex <= 'F') result += (*hex - 'A' +10); else if (*hex >= 'a' && *hex <= 'f') result += (*hex - 'a'+ 10); if (*++hex) //if the neext isn't a null result <<= 4; } return result; } unsigned int zigbee::hextoint(const char *hex) { //return 16 bit unsigned int result = 0; while (*hex) { //så længe det ikke er null if (*hex >= '0' && *hex <= '9') result += (*hex - '0'); else if (*hex >= 'A' && *hex <= 'F') result += (*hex - 'A' +10); else if (*hex >= 'a' && *hex <= 'f') result += (*hex - 'a'+ 10); if (*++hex) //if the neext isn't a null result <<= 4; } return result; } //--------------------------------------------------------------- void zigbee::SeePacket() { char *p; static uint8_t _pos; b = _zbee.getc(); // JHL : Validate that the incoming character is an ASCII character or CR/LF /*switch (b) { case CR: case LF: case ','...'}': break; default: // Non ASCII charater received! // printf("Non ASCII! %d\n\r", b); // _zbee.send_break(); return; } */ if ((b!=CR) && (b!=LF)) { _responseFrameString[_pos]=b; _pos=(_pos+1) % MAX_FRAME_DATA_SIZE; } if (b==CR) { // memcpy(&_responseFrameString,&_responseFrameData,_pos); GotFrame=1; _responseFrameString[_pos]=0; //Nul terminate _pos=0; // printf("%s \r\n",_responseFrameString); if (strstr(_responseFrameString,"+UCAST:")) { //returns on that we have sendt something //Do something } else if (strstr(_responseFrameString,"UCAST:")) { //checke for incoming UCAST data //if (sscanf (_responseFrameString,"UCAST:%X,%X=%s ",&EUI64,&framesize,Zdata)>0) p=strstr(_responseFrameString,"UCAST:"); p=p+6; strncpy(In.ID,p,16); In.ID[16]=0; //Zdat=1; p=strstr(_responseFrameString,"="); if (p) { p++; strcpy(In.Data,p); In.Ready=1; } } if (strstr(_responseFrameString,"+PANSCAN:")) { //info om nærliggende pan p=strstr(_responseFrameString,":"); p++; //P indholder nu SEQ nummer comma_parse(p,list,ZdataSize); PanVisible[NPanVisible].channel=atoi(list[0]); strcpy(PanVisible[NPanVisible].PID,list[1]); NPanVisible++; } if (strstr(_responseFrameString,"LeftPAN")) PanOnline=0; //Local node has left the Pan if (strstr(_responseFrameString,"LostPAN")) PanOnline=0; //Local node has left the Pan if (strstr(_responseFrameString,"ERROR:")) { p=strstr(_responseFrameString,":"); p++; //P indholder nu SEQ nummer ErrorCode=hextoint(p); } if (strstr(_responseFrameString,"NEWNODE:")) { //NEWNODE: <NodeID>,<EUI64>,<Parent NodeID> //new node on the pan p=strstr(_responseFrameString,"NEWNODE:"); p=p+13; NetInfo=1; strncpy(NetNodeID,p,16); } if ((strstr(_responseFrameString,"OK")>0) && (strstr(_responseFrameString,"TOKDUMP")==0) ) { //if (ScriptState) ConnectScript(); Ok=1; //Cmd=0; LineNo=0; } if (strstr(_responseFrameString,"FFD:")) { //FFD:000D6F00026C5BEA,0000 p=strstr(_responseFrameString,"FFD:"); p=p+4; NetInfo=1; strncpy(NetNodeID,p,16); } if (strstr(_responseFrameString,"N=")) { // sscanf (_responseFrameString,"+N=%s,%d,%d,%4X,",Devicetype,&channel,&NodeID,&EPID); size_t n; p=strstr(_responseFrameString,"="); p++; n=comma_parse(p,list,ZdataSize); strcpy(Devicetype,list[0]); AktuelPan.channel=atoi(list[1]); strcpy(AktuelPan.PID,list[3]); } if (strstr(_responseFrameString,"ACK")) { // PacketAck=1; p=strstr(_responseFrameString,":"); p++; //P indholder nu SEQ nummer SeqNumber=hextoint(p); } if (strstr(_responseFrameString,"NAK")) { PacketAck=0; p=strstr(_responseFrameString,":"); p++; //P indholder nu SEQ nummer SeqNumber=hextoint(p); } if (strstr(_responseFrameString,"SEQ")) { // // PacketAck=1; p=strstr(_responseFrameString,":"); p++; //P indholder nu SEQ nummer SeqNumber=hextoint(p); } if (strstr(_responseFrameString,"JPAN:")) { //JPAN:<channel>,<PID>,<EPID> p=strstr(_responseFrameString,":"); p++; comma_parse(p,list,ZdataSize); strcpy(Devicetype,list[0]); AktuelPan.channel=atoi(list[1]); strcpy(AktuelPan.PID,list[2]); PanOnline=1; } } } //-----------------------NON IRQ mode -------------------------------------------------------------------- void zigbee::readPacket() { //read and waits for the packet Timer t; t.reset(); t.start(); b=0; while((b!=CR) && (t.read_ms() < 1000)) if (_zbee.readable()) SeePacket(); t.stop(); } void zigbee::SletZdata(void){ int i; for (i=0; i<ZdataSize ; i++) In.Data[i]=0; }