takashi yamanoue
/
XBee_API_ex3
Xbee API Test 3
> 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: >
Diff: main.cpp
- 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); + } + } +}