XBee API operation library for mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers CoreAPI.cpp Source File

CoreAPI.cpp

00001 #include "CoreAPI.h"
00002 
00003 CoreAPI::CoreAPI(ISerial * serial, bool escape)
00004     :xBeeRx64Indicator(NULL),xBeeRx16Indicator(NULL),xBeeRx64IOSampleIndicator(NULL),xBeeRx16IOSampleIndicator(NULL),xBeeTxStatusIndicator(NULL),
00005      aTCommandIndicator(NULL),modemStatusIndicator(NULL),zigBeeTxStatusIndicator(NULL),zigBeeRxIndicator(NULL),
00006      zigBeeExplicitRxIndicator(NULL),zigBeeIOSampleIndicator(NULL),sensorReadIndicator(NULL),nodeIdentificationIndicator(NULL),
00007      remoteCommandIndicator(NULL),routeRecordIndicator(NULL),manyToOneRouteIndicator(NULL)
00008 {
00009     this->serial = serial;
00010     isEscapeMode = escape;
00011     msg = new APIFrame(INITIAL_FRAME_LENGTH);
00012     isChecksum = false;
00013 }
00014 
00015 CoreAPI::~CoreAPI()
00016 {
00017     if (msg != NULL)
00018         delete msg;
00019 
00020     if (serial != NULL)
00021         delete serial;
00022 }
00023 
00024 void CoreAPI::setVerifyChecksum(bool isCheck)
00025 {
00026     isChecksum = isCheck;
00027 }
00028 
00029 void CoreAPI::send(APIFrame * request)
00030 {
00031     request->calculateChecksum();
00032     int size = request->getPosition();
00033 
00034     serial->writeByte(KEY);
00035 
00036     writeByte(size >> 8);
00037     writeByte(size);
00038 
00039     for (int i = 0; i < size; i++)
00040         writeByte(request->get(i));
00041 
00042     writeByte(request->getCheckSum());
00043 }
00044 
00045 int CoreAPI::readByte()
00046 {
00047     int value = serial->readByte();
00048 
00049     if (isEscapeMode && value == ESCAPED)
00050         return serial->readByte() ^ 0x20;
00051 
00052     return value;
00053 }
00054 
00055 void CoreAPI::writeByte(unsigned char data)
00056 {
00057     if (isEscapeMode) {
00058         if (data == KEY || data == ESCAPED || data == XON || data == XOFF) {
00059             serial->writeByte(ESCAPED);
00060             serial->writeByte(data ^ 0x20);
00061             return;
00062         }
00063     }
00064 
00065     serial->writeByte(data);
00066 }
00067 
00068 APIFrame * CoreAPI::getResponse()
00069 {
00070     if (!serial->peek())
00071         return NULL;
00072 
00073     while (serial->readByte() != KEY);
00074 
00075     int length = getLength();
00076 
00077     msg->allocate(length);
00078 
00079     readPayLoad(length);
00080 
00081     if (isChecksum) {
00082         if (msg->verifyChecksum())
00083             return msg;
00084         else
00085             return NULL;
00086     } else return msg;
00087 }
00088 
00089 int CoreAPI::getLength()
00090 {
00091     int msb = readByte();
00092 
00093     int lsb = readByte();
00094 
00095     return (msb << 8) | lsb;
00096 }
00097 
00098 void CoreAPI::readPayLoad(int length)
00099 {
00100     for (int i = 0; i < length; i++)
00101         msg->set(readByte());
00102 
00103     msg->setCheckSum(readByte());
00104 }
00105 
00106 XBeeRx64Indicator * CoreAPI::getXBeeRx64()
00107 {
00108     if (getResponse() == NULL)
00109         return NULL;
00110 
00111     if (xBeeRx64Indicator.convert(msg))
00112         return &xBeeRx64Indicator;
00113     else return NULL;
00114 }
00115 
00116 XBeeRx16Indicator * CoreAPI::getXBeeRx16()
00117 {
00118     if (getResponse() == NULL)
00119         return NULL;
00120 
00121     if (xBeeRx16Indicator.convert(msg))
00122         return &xBeeRx16Indicator;
00123     else return NULL;
00124 }
00125 
00126 XBeeRx64IOSampleIndicator * CoreAPI::getXBeeRx64IOSample()
00127 {
00128     if (getResponse() == NULL)
00129         return NULL;
00130 
00131     if (xBeeRx64IOSampleIndicator.convert(msg))
00132         return &xBeeRx64IOSampleIndicator;
00133     else return NULL;
00134 }
00135 
00136 XBeeRx16IOSampleIndicator * CoreAPI::getXBeeRx16IOSample()
00137 {
00138     if (getResponse() == NULL)
00139         return NULL;
00140 
00141     if (xBeeRx16IOSampleIndicator.convert(msg))
00142         return &xBeeRx16IOSampleIndicator;
00143     else return NULL;
00144 }
00145 
00146 XBeeTxStatusIndicator * CoreAPI::getXBeeTxStatus()
00147 {
00148     if (getResponse() == NULL)
00149         return NULL;
00150 
00151     if (xBeeTxStatusIndicator.convert(msg))
00152         return &xBeeTxStatusIndicator;
00153     else return NULL;
00154 }
00155 
00156 ATCommandIndicator * CoreAPI::getATCommand()
00157 {
00158     if (getResponse() == NULL)
00159         return NULL;
00160 
00161     if (aTCommandIndicator.convert(msg))
00162         return &aTCommandIndicator;
00163     else return NULL;
00164 }
00165 
00166 ModemStatusIndicator * CoreAPI::getModemStatus()
00167 {
00168     if (getResponse() == NULL)
00169         return NULL;
00170 
00171     if (modemStatusIndicator.convert(msg))
00172         return &modemStatusIndicator;
00173     else return NULL;
00174 }
00175 
00176 ZigBeeTxStatusIndicator * CoreAPI::getZigBeeTxStatus()
00177 {
00178     if (getResponse() == NULL)
00179         return NULL;
00180 
00181     if (zigBeeTxStatusIndicator.convert(msg))
00182         return &zigBeeTxStatusIndicator;
00183     else return NULL;
00184 }
00185 
00186 ZigBeeRxIndicator * CoreAPI::getZigBeeRx()
00187 {
00188     if (getResponse() == NULL)
00189         return NULL;
00190 
00191     if (zigBeeRxIndicator.convert(msg))
00192         return &zigBeeRxIndicator;
00193     else return NULL;
00194 }
00195 
00196 ZigBeeExplicitRxIndicator * CoreAPI::getZigBeeExplicitRx()
00197 {
00198     if (getResponse() == NULL)
00199         return NULL;
00200 
00201     if (zigBeeExplicitRxIndicator.convert(msg))
00202         return &zigBeeExplicitRxIndicator;
00203     else return NULL;
00204 }
00205 
00206 ZigBeeIOSampleIndicator * CoreAPI::getZigBeeIOSample()
00207 {
00208     if (getResponse() == NULL)
00209         return NULL;
00210 
00211     if (zigBeeIOSampleIndicator.convert(msg))
00212         return &zigBeeIOSampleIndicator;
00213     else return NULL;
00214 }
00215 
00216 SensorReadIndicator * CoreAPI::getSensorRead()
00217 {
00218     if (getResponse() == NULL)
00219         return NULL;
00220 
00221     if (sensorReadIndicator.convert(msg))
00222         return &sensorReadIndicator;
00223     else return NULL;
00224 }
00225 
00226 NodeIdentificationIndicator * CoreAPI::getNodeIdentification()
00227 {
00228     if (getResponse() == NULL)
00229         return NULL;
00230 
00231     if (nodeIdentificationIndicator.convert(msg))
00232         return &nodeIdentificationIndicator;
00233     else return NULL;
00234 }
00235 
00236 RemoteCommandIndicator * CoreAPI::getRemoteCommand()
00237 {
00238     if (getResponse() == NULL)
00239         return NULL;
00240 
00241     if (remoteCommandIndicator.convert(msg))
00242         return &remoteCommandIndicator;
00243     else return NULL;
00244 }
00245 
00246 RouteRecordIndicator * CoreAPI::getRouteRecord()
00247 {
00248     if (getResponse() == NULL)
00249         return NULL;
00250 
00251     if (routeRecordIndicator.convert(msg))
00252         return &routeRecordIndicator;
00253     else return NULL;
00254 }
00255 
00256 ManyToOneRouteIndicator * CoreAPI::getManyToOneRoute()
00257 {
00258     if (getResponse() == NULL)
00259         return NULL;
00260 
00261     if (manyToOneRouteIndicator.convert(msg))
00262         return &manyToOneRouteIndicator;
00263     else return NULL;
00264 }
00265 
00266 XBeeTxStatusIndicator * CoreAPI::sendXBeeTx16(Address * remoteAddress, OptionsBase * option, const unsigned char * payload, int offset, int length)
00267 {
00268     waitFrameID++;
00269     if (waitFrameID == 0)
00270         waitFrameID = 0x01;
00271 
00272     msg->rewind();
00273     msg->set(APIFrame::Tx16_Request);
00274     msg->set(waitFrameID);
00275     msg->set(remoteAddress->getNetworkAddress() >> 8);
00276     msg->set(remoteAddress->getNetworkAddress());
00277     msg->set(option->getValue());
00278     msg->sets(payload, offset, length);
00279 
00280     send(msg);
00281 
00282     timer.start();
00283     for (int i = 0; i < 3; i++) {
00284         timer.reset();
00285         while (!serial->peek()) {
00286             if (timer.read_ms() > 1000) {
00287                 timer.stop();
00288                 return NULL;
00289             }
00290         }
00291 
00292         getResponse();
00293 
00294         if (xBeeTxStatusIndicator.convert(msg) && xBeeTxStatusIndicator.getFrameID() == waitFrameID) {
00295             timer.stop();
00296             return &xBeeTxStatusIndicator;
00297         }
00298     }
00299     timer.stop();
00300     return NULL;
00301 }
00302 
00303 XBeeTxStatusIndicator * CoreAPI::sendXBeeTx64(Address * remoteAddress, OptionsBase * option, const unsigned  char * payload, int offset, int length)
00304 {
00305     waitFrameID++;
00306     if (waitFrameID == 0)
00307         waitFrameID = 0x01;
00308 
00309     msg->rewind();
00310     msg->set(APIFrame::Tx64_Request);
00311     msg->set(waitFrameID);
00312     msg->sets(remoteAddress->getAddressValue(), 0, 8);
00313     msg->set(option->getValue());
00314     msg->sets(payload, offset, length);
00315 
00316     send(msg);
00317 
00318     timer.start();
00319     for (int i = 0; i < 3; i++) {
00320         timer.reset();
00321         while (!serial->peek()) {
00322             if (timer.read_ms() > 1000) {
00323                 timer.stop();
00324                 return NULL;
00325             }
00326         }
00327 
00328         getResponse();
00329 
00330         if (xBeeTxStatusIndicator.convert(msg) && xBeeTxStatusIndicator.getFrameID() == waitFrameID) {
00331             timer.stop();
00332             return &xBeeTxStatusIndicator;
00333         }
00334     }
00335     timer.stop();
00336     return NULL;
00337 }
00338 
00339 ATCommandIndicator * CoreAPI::sendATCommand(const char * command, bool applyChange, const unsigned  char * parameter, int offset, int length)
00340 {
00341     waitFrameID++;
00342     if (waitFrameID == 0)
00343         waitFrameID = 0x01;
00344 
00345     msg->rewind();
00346     if (applyChange)
00347         msg->set(APIFrame::AT_Command);
00348     else msg->set(APIFrame::AT_Command_Queue_Parameter_Value);
00349     msg->set(waitFrameID);
00350     msg->set(command[0]);
00351     msg->set(command[1]);
00352     if (parameter != NULL)
00353         msg->sets(parameter, offset, length);
00354 
00355     send(msg);
00356 
00357     timer.start();
00358     for (int i = 0; i < 3; i++) {
00359         timer.reset();
00360         while (!serial->peek()) {
00361             if (timer.read_ms() > 1000) {
00362                 timer.stop();
00363                 return NULL;
00364             }
00365         }
00366 
00367         getResponse();
00368 
00369         if (aTCommandIndicator.convert(msg) && aTCommandIndicator.getFrameID() == waitFrameID) {
00370             timer.stop();
00371             return &aTCommandIndicator;
00372         }
00373     }
00374     timer.stop();
00375     return NULL;
00376 }
00377 
00378 RemoteCommandIndicator * CoreAPI::sendRemoteATCommand(Address * remoteAddress, const char * command, OptionsBase * transmitOptions, const unsigned  char * parameter, int parameterOffset, int parameterLength)
00379 {
00380     waitFrameID++;
00381     if (waitFrameID == 0)
00382         waitFrameID = 0x01;
00383 
00384     msg->rewind();
00385     msg->set(APIFrame::Remote_Command_Request);
00386     msg->set(waitFrameID);
00387 
00388     msg->sets(remoteAddress->getAddressValue(), 0, 10);
00389     msg->set(transmitOptions->getValue());
00390     msg->set(command[0]);
00391     msg->set(command[1]);
00392 
00393     if (parameter != NULL)
00394         msg->sets(parameter, parameterOffset, parameterLength);
00395 
00396     send(msg);
00397 
00398     timer.start();
00399     for (int i = 0; i < 3; i++) {
00400         timer.reset();
00401         while (!serial->peek()) {
00402             if (timer.read_ms() > 1000) {
00403                 timer.stop();
00404                 return NULL;
00405             }
00406         }
00407 
00408         getResponse();
00409 
00410         if (remoteCommandIndicator.convert(msg) && remoteCommandIndicator.getFrameID() == waitFrameID) {
00411             timer.stop();
00412             return &remoteCommandIndicator;
00413         }
00414     }
00415     timer.stop();
00416     return NULL;
00417 }
00418 
00419 ZigBeeTxStatusIndicator * CoreAPI::sendZigBeeTx(Address * remoteAddress, OptionsBase * option, const unsigned  char * payload, int offset, int length)
00420 {
00421     waitFrameID++;
00422     if (waitFrameID == 0)
00423         waitFrameID = 0x01;
00424 
00425     msg->rewind();
00426     msg->set(APIFrame::ZigBee_Transmit_Request);
00427     msg->set(waitFrameID);
00428     msg->sets(remoteAddress->getAddressValue(), 0, 10);
00429     msg->set(0x00);
00430     msg->set(option->getValue());
00431     msg->sets(payload, offset, length);
00432 
00433     send(msg);
00434 
00435     timer.start();
00436     for (int i = 0; i < 3; i++) {
00437         timer.reset();
00438         while (!serial->peek()) {
00439             if (timer.read_ms() > 1000) {
00440                 timer.stop();
00441                 return NULL;
00442             }
00443         }
00444 
00445         getResponse();
00446 
00447         if (zigBeeTxStatusIndicator.convert(msg) && zigBeeTxStatusIndicator.getFrameID() == waitFrameID) {
00448             timer.stop();
00449             return &zigBeeTxStatusIndicator;
00450         }
00451     }
00452     timer.stop();
00453     return NULL;
00454 }
00455 
00456 ZigBeeTxStatusIndicator * CoreAPI::sendZigBeeExplicitTx(ExplicitAddress * remoteAddress, OptionsBase * option, const unsigned  char * payload, int offset, int length)
00457 {
00458     waitFrameID++;
00459     if (waitFrameID == 0)
00460         waitFrameID = 0x01;
00461 
00462     msg->rewind();
00463     msg->set(APIFrame::Explicit_Addressing_ZigBee_Command_Frame);
00464     msg->set(waitFrameID);
00465     msg->sets(remoteAddress->getAddressValue(), 0, 10);
00466     msg->sets(remoteAddress->getExplicitValue(), 0 , 6);
00467     msg->set(0x00);
00468     msg->set(option->getValue());
00469     msg->sets(payload, offset, length);
00470 
00471     send(msg);
00472 
00473     timer.start();
00474     for (int i = 0; i < 3; i++) {
00475         timer.reset();
00476         while (!serial->peek()) {
00477             if (timer.read_ms() > 1000) {
00478                 timer.stop();
00479                 return NULL;
00480             }
00481         }
00482 
00483         getResponse();
00484 
00485         if (zigBeeTxStatusIndicator.convert(msg) && zigBeeTxStatusIndicator.getFrameID() == waitFrameID) {
00486             timer.stop();
00487             return &zigBeeTxStatusIndicator;
00488         }
00489     }
00490     timer.stop();
00491     return NULL;
00492 }
00493 
00494 ATCommandIndicator * CoreAPI::setPinFunction (Pin * pin, unsigned char function)
00495 {
00496     return sendATCommand(pin->getCommand(), true, &function, 0 , 1);
00497 }
00498 
00499 ATCommandIndicator * CoreAPI::setIODetection(Pin ** pins, int size)
00500 {
00501     return sendATCommand(ATCommands::Digital_IO_Change_Detection, true, Pin::IOChangeDetectionConfiguration(pins, size));
00502 }
00503 
00504 RemoteCommandIndicator * CoreAPI::setRemotePinFunction (Address * remoteAddress, Pin * pin, unsigned char function)
00505 {
00506     return sendRemoteATCommand(remoteAddress, pin->getCommand(), RemoteCommandOptions::ApplyChanges, &function, 0 , 1);
00507 }
00508 
00509 RemoteCommandIndicator * CoreAPI::setRemoteIODetection(Address * remoteAddress, Pin ** pins, int size)
00510 {
00511     return sendRemoteATCommand(remoteAddress, ATCommands::Digital_IO_Change_Detection, RemoteCommandOptions::ApplyChanges, Pin::IOChangeDetectionConfiguration(pins, size), 0, 2);
00512 }
00513 
00514 bool CoreAPI::forceXBeeLocalIOSample()
00515 {
00516     ATCommandIndicator * re = sendATCommand(ATCommands::Force_Sample, true);
00517 
00518     if (re == NULL)
00519         return false;
00520 
00521     if (re->getCommandStatus() != 0x00)
00522         return false;
00523 
00524     return true;
00525 }
00526 
00527 IOSamples * CoreAPI::forceZigBeeLocalIOSample()
00528 {
00529     ATCommandIndicator * re = sendATCommand(ATCommands::Force_Sample, true);
00530 
00531     if (re == NULL)
00532         return NULL;
00533 
00534     return IOSampleDecoder::ZigBeeSamplesParse(re->getParameter());
00535 }
00536 
00537 IOSamples * CoreAPI::forceXBeeRemoteIOSample(Address * remote)
00538 {
00539     RemoteCommandIndicator * re = sendRemoteATCommand(remote, ATCommands::Force_Sample, OptionsBase::DEFAULT);
00540 
00541     return IOSampleDecoder::XBeeSamplesParse(re->getParameter());
00542 }
00543 
00544 IOSamples * CoreAPI::forceZigBeeRemoteIOSample(Address * remote)
00545 {
00546     RemoteCommandIndicator * re = sendRemoteATCommand(remote, ATCommands::Force_Sample, OptionsBase::DEFAULT);
00547 
00548     return IOSampleDecoder::ZigBeeSamplesParse(re->getParameter());
00549 }
00550