A libery to connect to telegesis zigbee module. Bassed on implemtation of XBEE

Fork of xbee_lib by Tristan Hughes

telegesis.cpp

Committer:
gert_lauritsen
Date:
2013-12-22
Revision:
26:2a85af491d92
Parent:
25:31120552e53c
Child:
27:a38b67f5be8f

File content as of revision 26:2a85af491d92:

#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);
#ifdef IRQCtrl
    _zbee.attach(this, &zigbee::SeePacket, Serial::RxIrq);
#endif
}

zigbee::~zigbee()
{
}

bool zigbee::Work()
{
    //read and waits for the packet
    bool datain=false;
    Timer t;
    t.reset();
    t.start();
    b=0;
    while((b!=CR) && (t.read_ms() < 200))
        if (_zbee.readable()) {
            datain=true;
            SeePacket();
        }
    t.stop();
    return datain;
    //if (_zbee.readable()) readPacket();
}

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();
    readPacket();
    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()
{
    _zbee.printf("ATZ\r");
    wait4OK();
    return 1;
}

int zigbee::ATI()
{
    GetSerial();
    return 1;
}


int zigbee::PingOut()
{
    //just return a OK (sends it ID out out the pan)
    _zbee.printf("AT+ANNCE\r");
    wait4OK();
    return 1;
}


int zigbee::PanScan()
{
    //
    _zbee.printf("AT+PANSCAN\r");
    return 1;
}


int zigbee::Establish_Network()
{
    //
    _zbee.printf("AT+EN\r");
    wait4JPAN();
    wait4OK();
    return 1;
}


int zigbee::LeaveNetwork()
{
    _zbee.printf("AT+DASSL\r");
    wait4OK();
    wait4Offline();
    return 1;
}

int zigbee::JoinNetwork()
{
    _zbee.printf("AT+JN\r");
    return 1;
}

int zigbee::ScanNetwork()
{
    _zbee.printf("AT+SN\r");
    return 1;
}

int zigbee::NetworkInfo()
{
//Return something like this "+N=COO,12,-11,29F0,55C0E0DCE605C522"
    _zbee.printf("AT+N\r");
    wait4OK();
    return 1;
}

int zigbee::UniCast(char *adr,char *payload)  //Ascii mode with null terminated string
{
    _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);
    return 1;
}

int zigbee::UniCastb(char *adr,char *payload, char payloadSize) //sends data in binary format
{
    _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;
}
//---------------------------------------------------------------
#ifdef IRQCtrl
void zigbee::readPacket()
{
    //read and waits for the packet
    Timer t;
    t.reset();
    t.start();
    while ((GotFrame==0) && (t.read_ms() < 500)) {}
    t.stop();
    GotFrame=0;
}

#endif

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(NetNodeID,p,16);
            NetNodeID[16]=0;
            Zdat=1;
            p=strstr(_responseFrameString,"=");
            if (p) {
                p++;
                strcpy(Zdata,p);
                Zdat=1;
            }
        }
        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);
            p=strstr(_responseFrameString,"+N=");
            p=p+3;
            strncpy(Devicetype,p,3);
            Devicetype[3]=0; //null termination
        }
        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);
        }
    }
}

//-----------------------NON IRQ mode --------------------------------------------------------------------
#ifndef IRQCtrl
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();
}

#endif