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.
Core/CoreAPI.cpp
- Committer:
- yangcq88517
- Date:
- 2015-10-26
- Revision:
- 3:6b205ec8624b
- Parent:
- 1:3dc0ec2f9fd6
- Child:
- 4:a0f1fba6c2fb
File content as of revision 3:6b205ec8624b:
#include "CoreAPI.h" CoreAPI::CoreAPI(ISerial * serial, bool escape) :xBeeRx64Indicator(NULL),xBeeRx16Indicator(NULL),xBeeRx64IOSampleIndicator(NULL),xBeeRx16IOSampleIndicator(NULL),xBeeTxStatusIndicator(NULL), aTCommandIndicator(NULL),modemStatusIndicator(NULL),zigBeeTxStatusIndicator(NULL),zigBeeRxIndicator(NULL), zigBeeExplicitRxIndicator(NULL),zigBeeIOSampleIndicator(NULL),sensorReadIndicator(NULL),nodeIdentificationIndicator(NULL), remoteCommandIndicator(NULL),routeRecordIndicator(NULL),manyToOneRouteIndicator(NULL) { this->serial = serial; isEscapeMode = escape; msg = new APIFrame(INITIAL_FRAME_LENGTH); isChecksum = false; isRunning = false; } CoreAPI::~CoreAPI() { if (msg != NULL) delete msg; if (serial != NULL) delete serial; } void CoreAPI::start() { if (!isRunning) { isRunning = true; if (!serial->isOpen()) serial->open(); } } void CoreAPI::stop() { if (isRunning) { isRunning = false; serial->close(); } } void CoreAPI::setVerifyChecksum(bool isCheck) { isChecksum = isCheck; } void CoreAPI::send(APIFrame * request) { if (!isRunning) return; request->calculateChecksum(); int size = request->getPosition(); serial->writeByte(KEY); writeByte(size >> 8); writeByte(size); for (int i = 0; i < size; i++) writeByte(request->get(i)); writeByte(request->getCheckSum()); } int CoreAPI::readByte() { int value = serial->readByte(); if (isEscapeMode && value == ESCAPED) return serial->readByte() ^ 0x20; return value; } void CoreAPI::writeByte(char data) { if (isEscapeMode) { if (data == KEY || data == ESCAPED || data == XON || data == XOFF) { serial->writeByte(ESCAPED); serial->writeByte(data ^ 0x20); return; } } serial->writeByte(data); } APIFrame * CoreAPI::getResponse() { if (!isRunning) return NULL; if (!serial->peek()) return NULL; while (serial->readByte() != KEY); int length = getLength(); msg->allocate(length); readPayLoad(length); if (isChecksum) { if (msg->verifyChecksum()) return msg; else return NULL; } else return msg; } int CoreAPI::getLength() { int msb = readByte(); int lsb = readByte(); return (msb << 8) | lsb; } void CoreAPI::readPayLoad(int length) { for (int i = 0; i < length; i++) msg->set(readByte()); msg->setCheckSum(readByte()); } XBeeRx64Indicator * CoreAPI::getXBeeRx64() { if (getResponse() == NULL) return NULL; if (xBeeRx64Indicator.convert(msg)) return &xBeeRx64Indicator; else return NULL; } XBeeRx16Indicator * CoreAPI::getXBeeRx16() { if (getResponse() == NULL) return NULL; if (xBeeRx16Indicator.convert(msg)) return &xBeeRx16Indicator; else return NULL; } XBeeRx64IOSampleIndicator * CoreAPI::getXBeeRx64IOSample() { if (getResponse() == NULL) return NULL; if (xBeeRx64IOSampleIndicator.convert(msg)) return &xBeeRx64IOSampleIndicator; else return NULL; } XBeeRx16IOSampleIndicator * CoreAPI::getXBeeRx16IOSample() { if (getResponse() == NULL) return NULL; if (xBeeRx16IOSampleIndicator.convert(msg)) return &xBeeRx16IOSampleIndicator; else return NULL; } XBeeTxStatusIndicator * CoreAPI::getXBeeTxStatus() { if (getResponse() == NULL) return NULL; if (xBeeTxStatusIndicator.convert(msg)) return &xBeeTxStatusIndicator; else return NULL; } ATCommandIndicator * CoreAPI::getATCommand() { if (getResponse() == NULL) return NULL; if (aTCommandIndicator.convert(msg)) return &aTCommandIndicator; else return NULL; } ModemStatusIndicator * CoreAPI::getModemStatus() { if (getResponse() == NULL) return NULL; if (modemStatusIndicator.convert(msg)) return &modemStatusIndicator; else return NULL; } ZigBeeTxStatusIndicator * CoreAPI::getZigBeeTxStatus() { if (getResponse() == NULL) return NULL; if (zigBeeTxStatusIndicator.convert(msg)) return &zigBeeTxStatusIndicator; else return NULL; } ZigBeeRxIndicator * CoreAPI::getZigBeeRx() { if (getResponse() == NULL) return NULL; if (zigBeeRxIndicator.convert(msg)) return &zigBeeRxIndicator; else return NULL; } ZigBeeExplicitRxIndicator * CoreAPI::getZigBeeExplicitRx() { if (getResponse() == NULL) return NULL; if (zigBeeExplicitRxIndicator.convert(msg)) return &zigBeeExplicitRxIndicator; else return NULL; } ZigBeeIOSampleIndicator * CoreAPI::getZigBeeIOSample() { if (getResponse() == NULL) return NULL; if (zigBeeIOSampleIndicator.convert(msg)) return &zigBeeIOSampleIndicator; else return NULL; } SensorReadIndicator * CoreAPI::getSensorRead() { if (getResponse() == NULL) return NULL; if (sensorReadIndicator.convert(msg)) return &sensorReadIndicator; else return NULL; } NodeIdentificationIndicator * CoreAPI::getNodeIdentification() { if (getResponse() == NULL) return NULL; if (nodeIdentificationIndicator.convert(msg)) return &nodeIdentificationIndicator; else return NULL; } RemoteCommandIndicator * CoreAPI::getRemoteCommand() { if (getResponse() == NULL) return NULL; if (remoteCommandIndicator.convert(msg)) return &remoteCommandIndicator; else return NULL; } RouteRecordIndicator * CoreAPI::getRouteRecord() { if (getResponse() == NULL) return NULL; if (routeRecordIndicator.convert(msg)) return &routeRecordIndicator; else return NULL; } ManyToOneRouteIndicator * CoreAPI::getManyToOneRoute() { if (getResponse() == NULL) return NULL; if (manyToOneRouteIndicator.convert(msg)) return &manyToOneRouteIndicator; else return NULL; } XBeeTxStatusIndicator * CoreAPI::sendXBeeTx16(Address * remoteAddress, OptionsBase * option, const char * payload, int offset, int length) { if (!isRunning) return NULL; waitFrameID++; if (waitFrameID == 0) waitFrameID = 0x01; msg->rewind(); msg->set(APIFrame::Tx16_Request); msg->set(waitFrameID); msg->set(remoteAddress->getNetworkAddress() >> 8); msg->set(remoteAddress->getNetworkAddress()); msg->set(option->getValue()); msg->sets(payload, offset, length); send(msg); timer.start(); for (int i = 0; i < 3; i++) { timer.reset(); while (!serial->peek()) { if (timer.read_ms() > 1000) { timer.stop(); return NULL; } } getResponse(); if (xBeeTxStatusIndicator.convert(msg) && xBeeTxStatusIndicator.getFrameID() == waitFrameID) { timer.stop(); return &xBeeTxStatusIndicator; } } timer.stop(); return NULL; } XBeeTxStatusIndicator * CoreAPI::sendXBeeTx64(Address * remoteAddress, OptionsBase * option, const char * payload, int offset, int length) { if (!isRunning) return NULL; waitFrameID++; if (waitFrameID == 0) waitFrameID = 0x01; msg->rewind(); msg->set(APIFrame::Tx64_Request); msg->set(waitFrameID); msg->sets(remoteAddress->getAddressValue(), 0, 8); msg->set(option->getValue()); msg->sets(payload, offset, length); send(msg); timer.start(); for (int i = 0; i < 3; i++) { timer.reset(); while (!serial->peek()) { if (timer.read_ms() > 1000) { timer.stop(); return NULL; } } getResponse(); if (xBeeTxStatusIndicator.convert(msg) && xBeeTxStatusIndicator.getFrameID() == waitFrameID) { timer.stop(); return &xBeeTxStatusIndicator; } } timer.stop(); return NULL; } ATCommandIndicator * CoreAPI::sendATCommand(const char * command, bool applyChange, const char * parameter, int offset, int length) { waitFrameID++; if (waitFrameID == 0) waitFrameID = 0x01; msg->rewind(); if (applyChange) msg->set(APIFrame::AT_Command); else msg->set(APIFrame::AT_Command_Queue_Parameter_Value); msg->set(waitFrameID); msg->sets(command, 0 , 2); if (parameter != NULL) msg->sets(parameter, offset, length); send(msg); timer.start(); for (int i = 0; i < 3; i++) { timer.reset(); while (!serial->peek()) { if (timer.read_ms() > 1000) { timer.stop(); return NULL; } } getResponse(); if (aTCommandIndicator.convert(msg) && aTCommandIndicator.getFrameID() == waitFrameID) { timer.stop(); return &aTCommandIndicator; } } timer.stop(); return NULL; } RemoteCommandIndicator * CoreAPI::sendRemoteATCommand(Address * remoteAddress, const char * command, OptionsBase * transmitOptions, const char * parameter, int parameterOffset, int parameterLength) { waitFrameID++; if (waitFrameID == 0) waitFrameID = 0x01; msg->rewind(); msg->set(APIFrame::Remote_Command_Request); msg->set(waitFrameID); msg->sets(remoteAddress->getAddressValue(), 0, 10); msg->set(transmitOptions->getValue()); msg->sets(command, 0, 2); if (parameter != NULL) msg->sets(parameter, parameterOffset, parameterLength); send(msg); timer.start(); for (int i = 0; i < 3; i++) { timer.reset(); while (!serial->peek()) { if (timer.read_ms() > 1000) { timer.stop(); return NULL; } } getResponse(); if (remoteCommandIndicator.convert(msg) && remoteCommandIndicator.getFrameID() == waitFrameID) { timer.stop(); return &remoteCommandIndicator; } } timer.stop(); return NULL; } ZigBeeTxStatusIndicator * CoreAPI::sendZigBeeTx(Address * remoteAddress, OptionsBase * option, const char * payload, int offset, int length) { waitFrameID++; if (waitFrameID == 0) waitFrameID = 0x01; msg->rewind(); msg->set(APIFrame::ZigBee_Transmit_Request); msg->set(waitFrameID); msg->sets(remoteAddress->getAddressValue(), 0, 10); msg->set(0x00); msg->set(option->getValue()); msg->sets(payload, offset, length); send(msg); timer.start(); for (int i = 0; i < 3; i++) { timer.reset(); while (!serial->peek()) { if (timer.read_ms() > 1000) { timer.stop(); return NULL; } } getResponse(); if (zigBeeTxStatusIndicator.convert(msg) && zigBeeTxStatusIndicator.getFrameID() == waitFrameID) { timer.stop(); return &zigBeeTxStatusIndicator; } } timer.stop(); return NULL; } ZigBeeTxStatusIndicator * CoreAPI::sendZigBeeExplicitTx(ExplicitAddress * remoteAddress, OptionsBase * option, const char * payload, int offset, int length) { waitFrameID++; if (waitFrameID == 0) waitFrameID = 0x01; msg->rewind(); msg->set(APIFrame::Explicit_Addressing_ZigBee_Command_Frame); msg->set(waitFrameID); msg->sets(remoteAddress->getAddressValue(), 0, 10); msg->sets(remoteAddress->getExplicitValue(), 0 , 6); msg->set(0x00); msg->set(option->getValue()); msg->sets(payload, offset, length); send(msg); timer.start(); for (int i = 0; i < 3; i++) { timer.reset(); while (!serial->peek()) { if (timer.read_ms() > 1000) { timer.stop(); return NULL; } } getResponse(); if (zigBeeTxStatusIndicator.convert(msg) && zigBeeTxStatusIndicator.getFrameID() == waitFrameID) { timer.stop(); return &zigBeeTxStatusIndicator; } } timer.stop(); return NULL; } ATCommandIndicator * CoreAPI::setPinFunction(Pin * pin, char function) { return sendATCommand(pin->getCommand(), true, &function, 0 , 1); } ATCommandIndicator * CoreAPI::setIODetection(Pin * pins, int size) { return sendATCommand(ATCommands::Digital_IO_Change_Detection, true, Pin::IOChangeDetectionConfiguration(pins, size)); } RemoteCommandIndicator * CoreAPI::setRemotePinFunction(Address * remoteAddress, Pin * pin, char function) { return sendRemoteATCommand(remoteAddress, pin->getCommand(), &RemoteCommandOptions::ApplyChanges, &function, 0 , 1); } RemoteCommandIndicator * CoreAPI::setRemoteIODetection(Address * remoteAddress, Pin * pins, int size) { return sendRemoteATCommand(remoteAddress, ATCommands::Digital_IO_Change_Detection, &RemoteCommandOptions::ApplyChanges, Pin::IOChangeDetectionConfiguration(pins, size)); } bool CoreAPI::forceXBeeLocalIOSample() { ATCommandIndicator * re = sendATCommand(ATCommands::Force_Sample, true); if (re == NULL) return false; if (re->getCommandStatus() != 0x00) return false; return true; } IOSamples * CoreAPI::forceZigBeeLocalIOSample() { ATCommandIndicator * re = sendATCommand(ATCommands::Force_Sample, true); if (re == NULL) return NULL; return IOSampleDecoder::ZigBeeSamplesParse(re->getParameter()); } IOSamples * CoreAPI::forceXBeeRemoteIOSample(Address * remote) { RemoteCommandIndicator * re = sendRemoteATCommand(remote, ATCommands::Force_Sample, &OptionsBase::DEFAULT); return IOSampleDecoder::XBeeSamplesParse(re->getParameter()); } IOSamples * CoreAPI::forceZigBeeRemoteIOSample(Address * remote) { RemoteCommandIndicator * re = sendRemoteATCommand(remote, ATCommands::Force_Sample, &OptionsBase::DEFAULT); return IOSampleDecoder::ZigBeeSamplesParse(re->getParameter()); }