XBee and XBee-PRO ZigBee RF modules provide cost-effective wireless connectivity to electronic devices. They are interoperable with other ZigBee PRO feature set devices, including devices from other vendors.

Dependencies:   BufferedArray

Dependents:   MBEDminiproject

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