Xbee API Test 3

Dependencies:   XBee mbed

> help
h or help
m <status-in-hex>,. ... Modem status
l <cmd>,<val-in-hex>.   ... exec <cmd> (AT) at this host.
lset fid <val-in-hex>. ... set local frame id. default is 1.
lset cmd <val-in-hex>. ... set local command.
lset val <val-in-hex>. ... set local command value.
q <cmd>,<val-in-hex>.   ... set queue parameter value.
r <cmd>,<val-in-hex>.   ... exec <cmd> (AT)at remote host.
rset a16 <val-in-hex>. ... set remote address high.
rset a64 <val-in-hex>,<val-in-hex>.  ... set remote address low.
rset fid <val-in-hex>. ... set remote frame id. default is 1.

> l D4,0x05
cmd=D4 val=0x05
apiId=88

object 100008c8:35 01 00 10 88 00 05 FE 04 01 00 FF

l OK:

> l D4,0x04
cmd=D4 val=0x04
apiId=88

object 100008c8:35 01 00 10 88 00 05 FE 04 01 00 FF

l OK:

>
Revision:
0:3edcfa3aba71
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sat Jul 21 04:09:54 2012 +0000
@@ -0,0 +1,569 @@
+#include "mbed.h"
+#include "XBee.h"
+#include "CQueue.h"
+#include "ResponseQueue.h"
+
+XBee xbee(p13, p14);
+Serial pc(USBTX, USBRX);
+Ticker tick;
+CQueue cq(256);
+ResponseQueue localResponseQueue;
+ResponseQueue remoteResponseQueue;
+
+uint8_t RemoteCmd[2];
+uint8_t LocalCmd[2];
+uint8_t RemoteVal[100];
+uint8_t LocalVal[100];
+AtCommandResponse response;
+RemoteAtCommandResponse remoteResp;
+ZBTxStatusResponse zbTxResp;
+ZBRxResponse zbRxResp;
+ZBRxIoSampleResponse zbRxIoResp;
+Rx64Response rx64Resp;
+Rx16Response rx16Resp;
+Rx64IoSampleResponse rx64IoResp;
+Rx16IoSampleResponse rx16IoResp;
+TxStatusResponse txStatusResp;
+FrameIdResponse frameIdResp;
+XBeeResponse xbResp;
+ModemStatusResponse modemStatusResp;
+
+/*
+#define TX_64_REQUEST 0x0
+#define TX_16_REQUEST 0x1
+#define AT_COMMAND_REQUEST 0x08
+#define AT_COMMAND_QUEUE_REQUEST 0x09
+#define REMOTE_AT_REQUEST 0x17
+#define ZB_TX_REQUEST 0x10
+#define ZB_EXPLICIT_TX_REQUEST 0x11
+#define RX_64_RESPONSE 0x80
+#define RX_16_RESPONSE 0x81
+#define RX_64_IO_RESPONSE 0x82
+#define RX_16_IO_RESPONSE 0x83
+#define AT_RESPONSE 0x88
+#define TX_STATUS_RESPONSE 0x89
+#define MODEM_STATUS_RESPONSE 0x8a
+#define ZB_RX_RESPONSE 0x90
+#define ZB_EXPLICIT_RX_RESPONSE 0x91
+#define ZB_TX_STATUS_RESPONSE 0x8b
+#define ZB_IO_SAMPLE_RESPONSE 0x92
+#define ZB_IO_NODE_IDENTIFIER_RESPONSE 0x95
+#define AT_COMMAND_RESPONSE 0x88
+#define REMOTE_AT_COMMAND_RESPONSE 0x97
+*/
+void copyObject(int size, uint8_t *source, uint8_t *destination){
+   for(int i=0;i<size;i++){
+      destination[i]=source[i];
+   }
+}
+
+void dumpObject(Serial *s, int size, uint8_t *object){
+   s->printf("object %x:",object);
+   for (int i = 0; i < size; i++) s->printf("%02X ", object[i]);
+   s->printf("\n\r");  
+}
+
+void getResponse(Serial *s){
+    AtCommandResponse *lrp;
+    RemoteAtCommandResponse *rrp;
+    uint8_t apiId;
+    xbee.readPacket();
+    if (!xbee.getResponse().isAvailable()) {
+        return;
+    } 
+//     s->printf("\n\r xbee getResponse isAvailable\n\r");
+        // Got a response! Check if response is AT command respose
+    apiId=xbee.getResponse().getApiId();
+    s->printf("apiId=%x\n\r",apiId);
+    if (apiId == AT_COMMAND_RESPONSE) {
+       lrp=(localResponseQueue.requestResponse());
+       (xbee.getResponse()).getAtCommandResponse((AtCommandResponse &)(*lrp));
+       localResponseQueue.putResponse(lrp);
+       return;
+//              s->printf(" putResponse done.\n\r");
+    } 
+    else  
+    if (apiId == REMOTE_AT_COMMAND_RESPONSE) {
+//            s->printf("RemoteAtCommand.\n\r");
+       rrp = (RemoteAtCommandResponse *)(remoteResponseQueue.requestResponse());
+       xbee.getResponse().getRemoteAtCommandResponse((RemoteAtCommandResponse &)(*rrp));
+       remoteResponseQueue.putResponse(rrp);
+       return;
+    }
+    else
+    if(apiId==RX_64_RESPONSE){
+       (xbee.getResponse()).getRx64Response(rx64Resp);
+    }
+    else
+    if(apiId==RX_16_RESPONSE){
+       (xbee.getResponse()).getRx16Response(rx16Resp);
+    }
+    else
+    if(apiId==RX_64_IO_RESPONSE){
+       (xbee.getResponse()).getRx64IoSampleResponse(rx64IoResp);
+    }
+    else
+    if(apiId==RX_16_IO_RESPONSE){
+       (xbee.getResponse()).getRx16IoSampleResponse(rx16IoResp);
+    }
+    else
+    if(apiId==TX_STATUS_RESPONSE ){
+       (xbee.getResponse()).getTxStatusResponse(txStatusResp);
+    }
+    else
+    if(apiId==MODEM_STATUS_RESPONSE ){
+       (xbee.getResponse()).getAtCommandResponse(modemStatusResp);
+    }
+    else
+    if(apiId==ZB_RX_RESPONSE){
+       (xbee.getResponse()).getZBRxResponse(zbRxResp);
+    }
+    else
+    if(apiId==ZB_TX_STATUS_RESPONSE ){
+       (xbee.getResponse()).getZBTxStatusResponse(zbTxResp); 
+    }
+    else
+    if(apiId==ZB_IO_SAMPLE_RESPONSE){
+       (xbee.getResponse()).getZBRxIoSampleResponse(zbRxIoResp);
+    }
+    else
+    if(apiId==MODEM_STATUS_RESPONSE){
+       (xbee.getResponse()).getModemStatusResponse(modemStatusResp);
+    }
+    else {
+          s->printf("Remote Command Error:0x%X\n", (xbee.getResponse()).getErrorCode());
+    }
+}
+
+void advance(){
+   int c;
+   if(pc.readable()){
+      c=pc.getc();
+      pc.putc(c); // echo-back
+      cq.putc(c);
+   }
+   getResponse(&pc);
+}
+
+int isStartWith(uint8_t *a, char *key){
+   while(*key!='\0' && *a!='\0'){
+      if(*a!=*key){
+         return 0;
+      }
+      a++;
+      key++;
+   }
+   if(*key=='\0') return 1;
+   return 0;
+}
+
+uint8_t *rmHeadIf(uint8_t *a, char *key){
+   uint8_t *ap;
+   char *kp;
+   ap=a; kp=key;
+   while(*kp!='\0' && *ap!='\0'){
+      if(*ap!=*kp){
+         return NULL;
+      }
+      ap++;
+      kp++;
+   }
+   if(*kp=='\0') return ap;
+   return NULL;
+}
+
+uint8_t *rmSpace(uint8_t *a){
+   while(*a!='\0'){
+      if(*a!=' '){
+         return a;
+      }
+      a++;
+   }
+   return a;
+}
+
+uint32_t s2uint32(uint8_t *s){
+   uint32_t x;
+   x=0;
+   if(isStartWith(s,"0x")){
+       s++; s++;
+       while(*s!='\0'){
+          if(*s>='0' && *s<='9'){
+             x=x<<4 |((*s)-'0');
+          }
+          else
+          if(*s>='a' && *s<='f'){
+             x=x<<4 | ((*s)-'a'+10);
+          }
+          else
+          if(*s>='A' && *s<='F'){
+             x=x<<4 | ((*s)-'A'+10);
+          }
+          s++;
+//          printf("\n\r x=%x\n\r",x);
+       }
+   }
+   else
+   if(*s>='0' && *s<='9'){
+       s++; s++;
+       while(*s!='\0'){
+          if(*s>='0' && *s<='9'){
+             x=x*10+(*s)-'0';
+          }
+          s++;
+       }
+   }   
+   return x;
+}
+uint16_t s2uint16(uint8_t *s){
+   uint16_t x;
+   x=0;
+   if(isStartWith(s,"0x")){
+       s++; s++;
+       while(*s!='\0' && *s!='.'){
+          if(*s>='0' && *s<='9'){
+             x=x<<4 |((*s)-'0');
+          }
+          else
+          if(*s>='a' && *s<='f'){
+             x=x<<4 | ((*s)-'a'+10);
+          }
+          else
+          if(*s>='A' && *s<='F'){
+             x=x<<4 | ((*s)-'A'+10);
+          }
+          s++;
+//          printf("\n\r x=%x\n\r",x);
+       }
+   }
+   else
+   if(*s>='0' && *s<='9'){
+       s++; s++;
+       while(*s!='\0'){
+          if(*s>='0' && *s<='9'){
+             x=x*10+(*s)-'0';
+          }
+          s++;
+       }
+   }   
+   return x;
+}
+
+int setStrConst(uint8_t *in, uint8_t *out){
+  int l=0;
+  if(*in!='\"') return 0;
+  in++;
+  while(*in!='\0'){
+    if(*in=='\\'){
+       in++;
+    }
+    if(*in=='\"'){
+       *out='\0';
+       return l;
+    }
+    l++;
+    in++;
+    out++;
+  }
+  return l;
+}
+
+char breaks1[]={'\n','\r',',',' ','\0'};
+char hexc[]={'0','1','2','3','4','5','6','7','8','9',
+             'a','A','b','B','c','C','d','D','e','E','f','F','\0'};
+char decs[]={'0','1','2','3','4','5','6','7','8','9'};
+char af[]={'a','b','c','d','e','f'};
+char AF[]={'A','B','C','D','E','F'};
+
+int isInLetters(char c, char *letters){
+   while(*letters!='\0'){
+      if(c==*letters) return 1;
+      letters++;
+   }
+   return 0;
+}
+
+void printHelp(Serial *s){
+   s->printf("h or help\n\r");
+   s->printf("m <status-in-hex>,. ... Modem status\n\r");
+   s->printf("l <cmd>,<val-in-hex>.   ... exec <cmd> (AT) at this host.\n\r");
+   s->printf("lset fid <val-in-hex>. ... set local frame id. default is 1.\n\r");
+   s->printf("lset cmd <val-in-hex>. ... set local command.\n\r");
+   s->printf("lset val <val-in-hex>. ... set local command value.\n\r");
+   s->printf("q <cmd>,<val-in-hex>.   ... set queue parameter value.\n\r");
+   s->printf("r <cmd>,<val-in-hex>.   ... exec <cmd> (AT)at remote host.\n\r");
+   s->printf("rset a16 <val-in-hex>. ... set remote address high.\n\r");
+   s->printf("rset a64 <val-in-hex>,<val-in-hex>.  ... set remote address low.\n\r");
+   s->printf("rset fid <val-in-hex>. ... set remote frame id. default is 1.\n\r");
+}
+
+void parseCommand(uint8_t *linep, uint8_t *cmd, uint8_t *val, uint8_t *vlength){
+   int l;
+   uint32_t x32;
+   uint8_t lv=0;
+   linep=rmSpace(linep);
+   cmd[0]=*linep; linep++;
+   cmd[1]=*linep; linep++;
+   linep=rmSpace(linep);
+   linep++; // skip ','
+   linep=rmSpace(linep);
+   l=strlen((char *)linep);
+   if(isStartWith(linep,"0x")){
+     if(l-2>=8){
+        x32=s2uint32(linep);
+        val[0]=x32>>24 & 0xff;
+        val[1]=x32>>16 & 0xff;
+        val[2]=x32>>8  & 0xff;
+        val[3]=x32 &0xff;
+        lv=4;
+     }
+     else
+     if(l-2>=4){
+        x32=s2uint32(linep);
+        val[0]=x32>>8  & 0xff;
+        val[1]=x32 & 0xff;
+        lv=2;
+     }
+     else
+     if(l-2>=1){
+        x32=s2uint32(linep);
+        val[0]=x32 & 0xff;
+        lv=1;
+     }
+   }
+   else
+   if(isStartWith(linep,"\"")){
+     lv=setStrConst(linep,val);
+   }      
+   else{
+     x32=s2uint32(linep);
+     val[0]=x32 & 0xff;
+     lv=1;
+   }
+   *vlength=lv;
+}
+
+void execLocalCommand(AtCommandRequest *r,uint8_t *cmd, uint8_t *val, uint8_t lv){
+   r->setCommand(cmd);
+   r->setCommandValue(val);
+   r->setCommandValueLength(lv);
+   xbee.send(*r);
+}
+
+void execRemoteCommand(RemoteAtCommandRequest *r,uint8_t *cmd, uint8_t *val, uint8_t lv ){
+   r->setCommand(cmd);
+   r->setCommandValue(val);
+   r->setCommandValueLength(lv);
+   xbee.send(*r);
+}
+
+char i2hc(int c){
+   char x=c & 0x0f;
+   if(x<=9){
+      x=x+'0';
+   }
+   else{
+      x=x-10+'a';
+   }
+   return x;
+}
+
+void a2hex(uint8_t *a, uint8_t len, char *hex){
+   *hex='0'; hex++;
+   *hex='x'; hex++;
+   *hex='\0';
+   while(len>0){
+      *hex=i2hc((*a>>4) & 0x0f);
+      hex++;
+      *hex=i2hc(*a & 0x0f);
+      hex++;
+      *hex='\0';
+      a++;
+      len--;
+   }
+   return;
+}
+uint8_t *rmHeadIfHex(Serial *s,uint8_t *linep, uint32_t *x32, uint8_t *length){
+   char hexline[20];
+   int l=0;
+   linep=rmSpace(linep);
+   if(isStartWith(linep,"0x")){
+     hexline[l]='0'; hexline[l+1]='x';
+     linep++; linep++; l++; l++;
+     if(!isInLetters(*linep,hexc)){
+        return NULL;
+     }
+     hexline[l]=*linep;
+     linep++; l++;
+     while(isInLetters(*linep,hexc)){
+       hexline[l]=*linep;
+       l++;
+       linep++;
+//       dumpObject(s,20,(uint8_t *)hexline);
+     }
+     hexline[l]='\0';
+     *x32=s2uint32((uint8_t *)hexline);
+     *length=l;
+     return linep;
+   }
+   return NULL;
+}
+void parseLocalSet(uint8_t *linep, AtCommandRequest *localRequest, uint8_t *localCmd, uint8_t *localVal,
+                   Serial *s){
+
+}
+int parseRemoteSet(uint8_t *linep, RemoteAtCommandRequest *remoteRequest, uint8_t *remoteCmd, uint8_t *remoteVal,
+                    Serial *s){
+   uint32_t x32_h,x32_l;
+   uint8_t l_h, l_l;
+   XBeeAddress64 remoteAddress64;
+   uint16_t x16;
+   uint8_t l;
+   linep=rmSpace(linep);
+   if((linep=rmHeadIf(linep,"a64 "))!=NULL){
+     linep=rmSpace(linep);
+     if((linep=rmHeadIfHex(s,linep, &x32_h, &l_h))==NULL) return 0;
+     remoteAddress64.setMsb(x32_h);
+     linep=rmSpace(linep);
+     if(*linep!=',') return 0;
+     linep++;
+     linep=rmSpace(linep);
+     if((linep=rmHeadIfHex(s,linep, &x32_l, &l_l))==NULL) return 0;
+     remoteAddress64.setLsb(x32_l);
+//     dumpObject(s,sizeof(*remoteRequest),(uint8_t *)remoteRequest);
+     remoteRequest->setRemoteAddress64(remoteAddress64);
+//     dumpObject(s,sizeof(*remoteRequest),(uint8_t *)remoteRequest);
+     s->printf("\n\r");
+     s->printf("cmd=rset a64 %x,%x\n\r",x32_h,x32_l);
+     return 1;
+   }
+   if((linep=rmHeadIf(linep,"a16 "))!=NULL){
+     linep=rmSpace(linep);
+     if((linep=rmHeadIfHex(s,linep, &x32_h, &l))==NULL) return 0;
+     x16=0x0000ffff & x32_h;
+     remoteRequest->setRemoteAddress16(x16);
+     s->printf("\n\r");
+     s->printf("cmd=lset a16 %x\n\r",x16);
+     return 1;
+   }     
+   return 0;
+}
+
+void localResponseOutput(Serial *s, AtCommandResponse *r){
+   dumpObject(s,sizeof(*r),(uint8_t *)r);
+            if ( r->getStatus() == AT_OK ) {
+               // Debug print
+                s->printf("\n\rl OK: ");
+                   for (int i = 0; i < r->getValueLength(); i++)
+                   s->printf("%02X ", r->getValue()[i]);
+                s->printf("\n\r");                
+            } else {
+                s->printf("\n\rl error: ");
+                   for (int i = 0; i < r->getValueLength(); i++)
+                   s->printf("%02X ", r->getValue()[i]);
+                s->printf("\n\r");                
+                s->printf("Local Command Error:0x%X\n\r", r->getStatus());   
+                s->printf("\n\rl errorCode=%x\n\r",r->getErrorCode());
+            }
+}
+void remoteResponseOutput(Serial *s, RemoteAtCommandResponse *r){
+               if ( r->getStatus() == AT_OK ) {
+               // Debug print
+                s->printf("\n\rr OK: ");
+                   for (int i = 0; i < r->getValueLength(); i++)
+                   s->printf("%02X ", r->getValue()[i]);
+                s->printf("\n\r");
+            } else {
+                s->printf("\n\rr err: ");
+                   for (int i = 0; i < r->getValueLength(); i++)
+                   s->printf("%02X ", r->getValue()[i]);
+                s->printf("\n\r");
+                s->printf("Remote Command Error:0x%X\n\r", r->getStatus());
+                s->printf("\n\rr errorCode=%x\n\r",r->getErrorCode());
+            }
+}
+
+int main() {
+    char inputLine[100];
+    char val[100];
+    uint8_t *linep;
+    uint8_t valLength;
+    XBeeAddress64 remoteAddress(0x0013A200, 0x403A8C82);
+    RemoteAtCommandRequest remoteRequest;
+    remoteRequest=RemoteAtCommandRequest();
+//    remoteRequest.setApiId((uint8_t)0x17);
+    remoteRequest.setRemoteAddress64(remoteAddress);
+    AtCommandRequest localRequest;
+    localRequest=AtCommandRequest();
+//    localRequest.setApiId((uint8_t)0x08);
+    AtCommandResponse * response = NULL, *lrx[5];
+    RemoteAtCommandResponse * remoteResp = NULL, *rrx[5];
+    localResponseQueue.init();
+    for(int i=0;i<5;i++){
+       lrx[i]=new AtCommandResponse();
+       localResponseQueue.collectResponse(lrx[i]);
+       rrx[i]=new RemoteAtCommandResponse();
+       remoteResponseQueue.collectResponse(rrx[i]);
+    }
+
+    wait(0.5);
+    pc.baud(115200);
+    printHelp(&pc);
+    pc.printf("\n\r ok-1?\n\r");
+    xbee.begin(115200); 
+    wait(0.5);
+    tick.attach(&advance, 0.001); // the address of the function to be attached (flip) and the interval (2 seconds)
+    pc.printf("\n\r ok-2?\n\r");
+    /*
+    for(int i=0;i<5;i++){
+       dumpObject(&pc,sizeof(*lrx[i]),(uint8_t *)lrx[i]);
+       dumpObject(&pc,sizeof(*rrx[i]),(uint8_t *)rrx[i]);
+    }
+    */
+    while(1){ 
+      pc.printf("\n\r");
+      if((response=localResponseQueue.getResponse())!=NULL){
+          localResponseOutput(&pc, response);
+          localResponseQueue.collectResponse(response);
+      }
+      else
+      if((remoteResp=(RemoteAtCommandResponse *)(remoteResponseQueue.getResponse()))!=NULL){
+          remoteResponseOutput(&pc, remoteResp);
+          remoteResponseQueue.collectResponse(remoteResp);
+      }
+      else{
+        pc.printf("> ");
+        cq.getString(inputLine,100);
+        if(rmHeadIf((uint8_t *)inputLine,"h")){
+          pc.printf("\n\r");
+          printHelp(&pc);
+        }
+        else
+        if((linep=rmHeadIf((uint8_t *)inputLine,"l "))!=NULL){
+          parseCommand(linep,LocalCmd, LocalVal, &valLength);
+          a2hex(LocalVal,valLength,val);
+          pc.printf("\n\r");
+          pc.printf("cmd=%c%c val=%s\n\r",LocalCmd[0],LocalCmd[1],val);
+          execLocalCommand(&localRequest, LocalCmd, LocalVal, valLength);
+        }
+        else
+        if((linep=rmHeadIf((uint8_t *)inputLine,"r "))!=NULL){
+          parseCommand(linep, RemoteCmd, RemoteVal, &valLength);
+          a2hex(RemoteVal,valLength,val);
+          pc.printf("\n\r");
+          pc.printf("cmd=%c%c val=%s\n\r",RemoteCmd[0],RemoteCmd[1],val);
+          execRemoteCommand(&remoteRequest, RemoteCmd, RemoteVal, valLength);
+        }
+        else
+        if((linep=rmHeadIf((uint8_t *)inputLine,"lset "))!=NULL){
+          parseLocalSet(linep,&localRequest, LocalCmd, LocalVal,&pc);
+        }
+        else
+        if((linep=rmHeadIf((uint8_t *)inputLine,"rset "))!=NULL){
+          parseRemoteSet(linep,&remoteRequest, RemoteCmd, RemoteVal,&pc);
+        }
+
+        wait(0.1);
+      }
+    }
+}