David Dollar / XBee

Dependents:   MachineCloud

Fork of XBee by Suga koubou

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers XBee.cpp Source File

XBee.cpp

Go to the documentation of this file.
00001 /**
00002  * XBee-mbed library
00003  * Modified for mbed, 2011 Suga.
00004  *
00005  *
00006  * Copyright (c) 2009 Andrew Rapp. All rights reserved.
00007  *
00008  * This file is part of XBee-Arduino.
00009  *
00010  * XBee-Arduino is free software: you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation, either version 3 of the License, or
00013  * (at your option) any later version.
00014  *
00015  * XBee-Arduino is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License
00021  * along with XBee-Arduino.  If not, see <http://www.gnu.org/licenses/>.
00022  */
00023 
00024 /** @file
00025  * @brief XBee library for mbed
00026  */
00027 
00028 //#define DEBUG
00029 #include "dbg.h"
00030 
00031 #include "mbed.h"
00032 #include "XBee.h"
00033 
00034 XBeeResponse::XBeeResponse() {
00035 
00036 }
00037 
00038 uint8_t XBeeResponse::getApiId() {
00039     return _apiId;
00040 }
00041 
00042 void XBeeResponse::setApiId(uint8_t apiId) {
00043     _apiId = apiId;
00044 }
00045 
00046 uint8_t XBeeResponse::getMsbLength() {
00047     return _msbLength;
00048 }
00049 
00050 void XBeeResponse::setMsbLength(uint8_t msbLength) {
00051     _msbLength = msbLength;
00052 }
00053 
00054 uint8_t XBeeResponse::getLsbLength() {
00055     return _lsbLength;
00056 }
00057 
00058 void XBeeResponse::setLsbLength(uint8_t lsbLength) {
00059     _lsbLength = lsbLength;
00060 }
00061 
00062 uint8_t XBeeResponse::getChecksum() {
00063     return _checksum;
00064 }
00065 
00066 void XBeeResponse::setChecksum(uint8_t checksum) {
00067     _checksum = checksum;
00068 }
00069 
00070 uint16_t XBeeResponse::getFrameDataLength() {
00071     return _frameLength;
00072 }
00073 
00074 void XBeeResponse::setFrameLength(uint16_t frameLength) {
00075     _frameLength = frameLength;
00076 }
00077 
00078 bool XBeeResponse::isAvailable() {
00079     return _complete;
00080 }
00081 
00082 void XBeeResponse::setAvailable(bool complete) {
00083     _complete = complete;
00084 }
00085 
00086 bool XBeeResponse::isError() {
00087     return _errorCode > 0;
00088 }
00089 
00090 uint8_t XBeeResponse::getErrorCode() {
00091     return _errorCode;
00092 }
00093 
00094 void XBeeResponse::setErrorCode(uint8_t errorCode) {
00095     _errorCode = errorCode;
00096 }
00097 
00098 // copy common fields from xbee response to target response
00099 void XBeeResponse::setCommon(XBeeResponse &target) {
00100     target.setApiId(getApiId());
00101     target.setAvailable(isAvailable());
00102     target.setChecksum(getChecksum());
00103     target.setErrorCode(getErrorCode());
00104     target.setFrameLength(getFrameDataLength());
00105     target.setMsbLength(getMsbLength());
00106     target.setLsbLength(getLsbLength());
00107 }
00108 
00109 #ifdef SERIES_2
00110 
00111 ZBTxStatusResponse::ZBTxStatusResponse() : FrameIdResponse() {
00112 
00113 }
00114 
00115 uint16_t ZBTxStatusResponse::getRemoteAddress() {
00116     return  (getFrameData()[1] << 8) + getFrameData()[2];
00117 }
00118 
00119 uint8_t ZBTxStatusResponse::getTxRetryCount() {
00120     return getFrameData()[3];
00121 }
00122 
00123 uint8_t ZBTxStatusResponse::getDeliveryStatus() {
00124     return getFrameData()[4];
00125 }
00126 
00127 uint8_t ZBTxStatusResponse::getDiscoveryStatus() {
00128     return getFrameData()[5];
00129 }
00130 
00131 bool ZBTxStatusResponse::isSuccess() {
00132     return getDeliveryStatus() == SUCCESS;
00133 }
00134 
00135 void XBeeResponse::getZBTxStatusResponse(XBeeResponse &zbXBeeResponse) {
00136 
00137     // way off?
00138     ZBTxStatusResponse* zb = static_cast<ZBTxStatusResponse*>(&zbXBeeResponse);
00139     // pass pointer array to subclass
00140     zb->setFrameData(getFrameData());
00141     setCommon(zbXBeeResponse);
00142 }
00143 
00144 ZBRxResponse::ZBRxResponse(): RxDataResponse() {
00145     _remoteAddress64 = XBeeAddress64();
00146 }
00147 
00148 uint16_t ZBRxResponse::getRemoteAddress16() {
00149     return     (getFrameData()[8] << 8) + getFrameData()[9];
00150 }
00151 
00152 uint8_t ZBRxResponse::getOption() {
00153     return getFrameData()[10];
00154 }
00155 
00156 // markers to read data from packet array.  this is the index, so the 12th item in the array
00157 uint8_t ZBRxResponse::getDataOffset() {
00158     return 11;
00159 }
00160 
00161 uint16_t ZBRxResponse::getDataLength() {
00162     return getPacketLength() - getDataOffset() - 1;
00163 }
00164 
00165 XBeeAddress64& ZBRxResponse::getRemoteAddress64() {
00166     return _remoteAddress64;
00167 }
00168 
00169 void XBeeResponse::getZBRxResponse(XBeeResponse &rxResponse) {
00170 
00171     ZBRxResponse* zb = static_cast<ZBRxResponse*>(&rxResponse);
00172 
00173     //TODO verify response api id matches this api for this response
00174 
00175     // pass pointer array to subclass
00176     zb->setFrameData(getFrameData());
00177     setCommon(rxResponse);
00178 
00179     zb->getRemoteAddress64().setMsb((uint32_t(getFrameData()[0]) << 24) + (uint32_t(getFrameData()[1]) << 16) + (uint16_t(getFrameData()[2]) << 8) + getFrameData()[3]);
00180     zb->getRemoteAddress64().setLsb((uint32_t(getFrameData()[4]) << 24) + (uint32_t(getFrameData()[5]) << 16) + (uint16_t(getFrameData()[6]) << 8) + (getFrameData()[7]));
00181 }
00182 
00183 
00184 ZBRxIoSampleResponse::ZBRxIoSampleResponse() : ZBRxResponse() {
00185 
00186 }
00187 
00188 // 64 + 16 addresses, sample size, option = 12 (index 11), so this starts at 12
00189 uint8_t ZBRxIoSampleResponse::getDigitalMaskMsb() {
00190     return getFrameData()[12] & 0x1c;
00191 }
00192 
00193 uint8_t ZBRxIoSampleResponse::getDigitalMaskLsb() {
00194     return getFrameData()[13];
00195 }
00196 
00197 uint8_t ZBRxIoSampleResponse::getAnalogMask() {
00198     return getFrameData()[14] & 0x8f;
00199 }
00200 
00201 bool ZBRxIoSampleResponse::containsAnalog() {
00202     return getAnalogMask() > 0;
00203 }
00204 
00205 bool ZBRxIoSampleResponse::containsDigital() {
00206     return getDigitalMaskMsb() > 0 || getDigitalMaskLsb() > 0;
00207 }
00208 
00209 bool ZBRxIoSampleResponse::isAnalogEnabled(uint8_t pin) {
00210     return ((getAnalogMask() >> pin) & 1) == 1;
00211 }
00212 
00213 bool ZBRxIoSampleResponse::isDigitalEnabled(uint8_t pin) {
00214     if (pin <= 7) {
00215         // added extra parens to calm avr compiler
00216         return ((getDigitalMaskLsb() >> pin) & 1) == 1;
00217     } else {
00218         return ((getDigitalMaskMsb() >> (pin - 8)) & 1) == 1;
00219     }
00220 }
00221 
00222 uint16_t ZBRxIoSampleResponse::getAnalog(uint8_t pin) {
00223     // analog starts 13 bytes after sample size, if no dio enabled
00224     uint8_t start = 15;
00225 
00226     if (containsDigital()) {
00227         // make room for digital i/o
00228         start+=2;
00229     }
00230 
00231 //    std::cout << "spacing is " << static_cast<unsigned int>(spacing) << std::endl;
00232 
00233     // start depends on how many pins before this pin are enabled
00234     for (int i = 0; i < pin; i++) {
00235 //        if (isAnalogEnabled(pin)) {
00236         if (isAnalogEnabled(i)) {
00237             start+=2;
00238         }
00239     }
00240 
00241 //    std::cout << "start for analog pin ["<< static_cast<unsigned int>(pin) << "]/sample " << static_cast<unsigned int>(sample) << " is " << static_cast<unsigned int>(start) << std::endl;
00242 
00243 //    std::cout << "returning index " << static_cast<unsigned int>(getSampleOffset() + start) << " and index " <<  static_cast<unsigned int>(getSampleOffset() + start + 1) << ", val is " << static_cast<unsigned int>(getFrameData()[getSampleOffset() + start] << 8) <<  " and " <<  + static_cast<unsigned int>(getFrameData()[getSampleOffset() + start + 1]) << std::endl;
00244 
00245     return (uint16_t)((getFrameData()[start] << 8) + getFrameData()[start + 1]);
00246 }
00247 
00248 bool ZBRxIoSampleResponse::isDigitalOn(uint8_t pin) {
00249     if (pin <= 7) {
00250         // D0-7
00251         // DIO LSB is index 5
00252         return ((getFrameData()[16] >> pin) & 1) == 1;
00253     } else {
00254         // D10-12
00255         // DIO MSB is index 4
00256         return ((getFrameData()[15] >> (pin - 8)) & 1) == 1;
00257     }
00258 }
00259 
00260 void XBeeResponse::getZBRxIoSampleResponse(XBeeResponse &response) {
00261     ZBRxIoSampleResponse* zb = static_cast<ZBRxIoSampleResponse*>(&response);
00262 
00263 
00264     // pass pointer array to subclass
00265     zb->setFrameData(getFrameData());
00266     setCommon(response);
00267 
00268     zb->getRemoteAddress64().setMsb((uint32_t(getFrameData()[0]) << 24) + (uint32_t(getFrameData()[1]) << 16) + (uint16_t(getFrameData()[2]) << 8) + getFrameData()[3]);
00269     zb->getRemoteAddress64().setLsb((uint32_t(getFrameData()[4]) << 24) + (uint32_t(getFrameData()[5]) << 16) + (uint16_t(getFrameData()[6]) << 8) + (getFrameData()[7]));
00270 }
00271 
00272 #endif
00273 
00274 #ifdef SERIES_1
00275 
00276 RxResponse::RxResponse() : RxDataResponse() {
00277 
00278 }
00279 
00280 uint16_t Rx16Response::getRemoteAddress16() {
00281     return (getFrameData()[0] << 8) + getFrameData()[1];
00282 }
00283 
00284 XBeeAddress64& Rx64Response::getRemoteAddress64() {
00285     return _remoteAddress;
00286 }
00287 
00288 Rx64Response::Rx64Response() : RxResponse() {
00289     _remoteAddress = XBeeAddress64();
00290 }
00291 
00292 Rx16Response::Rx16Response() : RxResponse() {
00293 
00294 }
00295 
00296 RxIoSampleBaseResponse::RxIoSampleBaseResponse() : RxResponse() {
00297 
00298 }
00299 
00300 uint8_t RxIoSampleBaseResponse::getSampleOffset() {
00301     // sample starts 2 bytes after rssi
00302     return getRssiOffset() + 2;
00303 }
00304 
00305 
00306 uint8_t RxIoSampleBaseResponse::getSampleSize() {
00307     return getFrameData()[getSampleOffset()];
00308 }
00309 
00310 bool RxIoSampleBaseResponse::containsAnalog() {
00311     return (getFrameData()[getSampleOffset() + 1] & 0x7e) > 0;
00312 }
00313 
00314 bool RxIoSampleBaseResponse::containsDigital() {
00315     return (getFrameData()[getSampleOffset() + 1] & 0x1) > 0 || getFrameData()[getSampleOffset() + 2] > 0;
00316 }
00317 
00318 //uint16_t RxIoSampleBaseResponse::getAnalog0(uint8_t sample) {
00319 //    return getAnalog(0, sample);
00320 //}
00321 
00322 bool RxIoSampleBaseResponse::isAnalogEnabled(uint8_t pin) {
00323     return (((getFrameData()[getSampleOffset() + 1] >> (pin + 1)) & 1) == 1);
00324 }
00325 
00326 bool RxIoSampleBaseResponse::isDigitalEnabled(uint8_t pin) {
00327     if (pin < 8) {
00328         return ((getFrameData()[getSampleOffset() + 4] >> pin) & 1) == 1;
00329     } else {
00330         return (getFrameData()[getSampleOffset() + 3] & 1) == 1;
00331     }
00332 }
00333 
00334 uint16_t RxIoSampleBaseResponse::getAnalog(uint8_t pin, uint8_t sample) {
00335 
00336     // analog starts 3 bytes after sample size, if no dio enabled
00337     uint8_t start = 3;
00338 
00339     if (containsDigital()) {
00340         // make room for digital i/o sample (2 bytes per sample)
00341         start+=2*(sample + 1);
00342     }
00343 
00344     uint8_t spacing = 0;
00345 
00346     // spacing between samples depends on how many are enabled. add one for each analog that's enabled
00347     for (int i = 0; i <= 5; i++) {
00348         if (isAnalogEnabled(i)) {
00349             // each analog is two bytes
00350             spacing+=2;
00351         }
00352     }
00353 
00354 //    std::cout << "spacing is " << static_cast<unsigned int>(spacing) << std::endl;
00355 
00356     // start depends on how many pins before this pin are enabled
00357     for (int i = 0; i < pin; i++) {
00358         if (isAnalogEnabled(pin)) {
00359             start+=2;
00360         }
00361     }
00362 
00363     start+= sample * spacing;
00364 
00365 //    std::cout << "start for analog pin ["<< static_cast<unsigned int>(pin) << "]/sample " << static_cast<unsigned int>(sample) << " is " << static_cast<unsigned int>(start) << std::endl;
00366 
00367 //    std::cout << "returning index " << static_cast<unsigned int>(getSampleOffset() + start) << " and index " <<  static_cast<unsigned int>(getSampleOffset() + start + 1) << ", val is " << static_cast<unsigned int>(getFrameData()[getSampleOffset() + start] << 8) <<  " and " <<  + static_cast<unsigned int>(getFrameData()[getSampleOffset() + start + 1]) << std::endl;
00368 
00369     return (uint16_t)((getFrameData()[getSampleOffset() + start] << 8) + getFrameData()[getSampleOffset() + start + 1]);
00370 }
00371 
00372 bool RxIoSampleBaseResponse::isDigitalOn(uint8_t pin, uint8_t sample) {
00373     if (pin < 8) {
00374         return ((getFrameData()[getSampleOffset() + 4] >> pin) & 1) == 1;
00375     } else {
00376         return (getFrameData()[getSampleOffset() + 3] & 1) == 1;
00377     }
00378 }
00379 
00380 
00381 //bool RxIoSampleBaseResponse::isDigital0On(uint8_t sample) {
00382 //    return isDigitalOn(0, sample);
00383 //}
00384 
00385 Rx16IoSampleResponse::Rx16IoSampleResponse() : RxIoSampleBaseResponse() {
00386 
00387 }
00388 
00389 uint16_t Rx16IoSampleResponse::getRemoteAddress16() {
00390     return (uint16_t)((getFrameData()[0] << 8) + getFrameData()[1]);
00391 }
00392 
00393 uint8_t Rx16IoSampleResponse::getRssiOffset() {
00394     return 2;
00395 }
00396 
00397 void XBeeResponse::getRx16IoSampleResponse(XBeeResponse &response) {
00398     Rx16IoSampleResponse* rx = static_cast<Rx16IoSampleResponse*>(&response);
00399 
00400     rx->setFrameData(getFrameData());
00401     setCommon(response);
00402 }
00403 
00404 
00405 Rx64IoSampleResponse::Rx64IoSampleResponse() : RxIoSampleBaseResponse() {
00406     _remoteAddress = XBeeAddress64();
00407 }
00408 
00409 XBeeAddress64& Rx64IoSampleResponse::getRemoteAddress64() {
00410     return _remoteAddress;
00411 }
00412 
00413 uint8_t Rx64IoSampleResponse::getRssiOffset() {
00414     return 8;
00415 }
00416 
00417 void XBeeResponse::getRx64IoSampleResponse(XBeeResponse &response) {
00418     Rx64IoSampleResponse* rx = static_cast<Rx64IoSampleResponse*>(&response);
00419 
00420     rx->setFrameData(getFrameData());
00421     setCommon(response);
00422 
00423     rx->getRemoteAddress64().setMsb((uint32_t(getFrameData()[0]) << 24) + (uint32_t(getFrameData()[1]) << 16) + (uint16_t(getFrameData()[2]) << 8) + getFrameData()[3]);
00424     rx->getRemoteAddress64().setLsb((uint32_t(getFrameData()[4]) << 24) + (uint32_t(getFrameData()[5]) << 16) + (uint16_t(getFrameData()[6]) << 8) + getFrameData()[7]);
00425 }
00426 
00427 TxStatusResponse::TxStatusResponse() : FrameIdResponse() {
00428 
00429 }
00430 
00431 uint8_t TxStatusResponse::getStatus() {
00432     return getFrameData()[1];
00433 }
00434 
00435 bool TxStatusResponse::isSuccess() {
00436     return getStatus() == SUCCESS;
00437 }
00438 
00439 void XBeeResponse::getTxStatusResponse(XBeeResponse &txResponse) {
00440 
00441     TxStatusResponse* txStatus = static_cast<TxStatusResponse*>(&txResponse);
00442 
00443     // pass pointer array to subclass
00444     txStatus->setFrameData(getFrameData());
00445     setCommon(txResponse);
00446 }
00447 
00448 uint8_t RxResponse::getRssi() {
00449     return getFrameData()[getRssiOffset()];
00450 }
00451 
00452 uint8_t RxResponse::getOption() {
00453     return getFrameData()[getRssiOffset() + 1];
00454 }
00455 
00456 bool RxResponse::isAddressBroadcast() {
00457     return (getOption() & 2) == 2;
00458 }
00459 
00460 bool RxResponse::isPanBroadcast() {
00461     return (getOption() & 4) == 4;
00462 }
00463 
00464 uint16_t RxResponse::getDataLength() {
00465     return getPacketLength() - getDataOffset() - 1;
00466 }
00467 
00468 uint8_t RxResponse::getDataOffset() {
00469     return getRssiOffset() + 2;
00470 }
00471 
00472 uint8_t Rx16Response::getRssiOffset() {
00473     return RX_16_RSSI_OFFSET;
00474 }
00475 
00476 void XBeeResponse::getRx16Response(XBeeResponse &rx16Response) {
00477 
00478     Rx16Response* rx16 = static_cast<Rx16Response*>(&rx16Response);
00479 
00480     // pass pointer array to subclass
00481     rx16->setFrameData(getFrameData());
00482     setCommon(rx16Response);
00483 
00484 //    rx16->getRemoteAddress16().setAddress((getFrameData()[0] << 8) + getFrameData()[1]);
00485 }
00486 
00487 uint8_t Rx64Response::getRssiOffset() {
00488     return RX_64_RSSI_OFFSET;
00489 }
00490 
00491 void XBeeResponse::getRx64Response(XBeeResponse &rx64Response) {
00492 
00493     Rx64Response* rx64 = static_cast<Rx64Response*>(&rx64Response);
00494 
00495     // pass pointer array to subclass
00496     rx64->setFrameData(getFrameData());
00497     setCommon(rx64Response);
00498 
00499     rx64->getRemoteAddress64().setMsb((uint32_t(getFrameData()[0]) << 24) + (uint32_t(getFrameData()[1]) << 16) + (uint16_t(getFrameData()[2]) << 8) + getFrameData()[3]);
00500     rx64->getRemoteAddress64().setLsb((uint32_t(getFrameData()[4]) << 24) + (uint32_t(getFrameData()[5]) << 16) + (uint16_t(getFrameData()[6]) << 8) + getFrameData()[7]);
00501 }
00502 
00503 #endif
00504 
00505 RemoteAtCommandResponse::RemoteAtCommandResponse() : AtCommandResponse() {
00506 
00507 }
00508 
00509 uint8_t* RemoteAtCommandResponse::getCommand() {
00510     return getFrameData() + 11;
00511 }
00512 
00513 uint8_t RemoteAtCommandResponse::getStatus() {
00514     return getFrameData()[13];
00515 }
00516 
00517 bool RemoteAtCommandResponse::isOk() {
00518     // weird c++ behavior.  w/o this method, it calls AtCommandResponse::isOk(), which calls the AtCommandResponse::getStatus, not this.getStatus!!!
00519     return getStatus() == AT_OK;
00520 }
00521 
00522 uint16_t RemoteAtCommandResponse::getValueLength() {
00523     return getFrameDataLength() - 14;
00524 }
00525 
00526 uint8_t* RemoteAtCommandResponse::getValue() {
00527     if (getValueLength() > 0) {
00528         // value is only included for query commands.  set commands does not return a value
00529         return getFrameData() + 14;
00530     }
00531 
00532     return NULL;
00533 }
00534 
00535 uint16_t RemoteAtCommandResponse::getRemoteAddress16() {
00536     return uint16_t((getFrameData()[9] << 8) + getFrameData()[10]);
00537 }
00538 
00539 XBeeAddress64& RemoteAtCommandResponse::getRemoteAddress64() {
00540     return _remoteAddress64;
00541 }
00542 
00543 void XBeeResponse::getRemoteAtCommandResponse(XBeeResponse &response) {
00544 
00545     // TODO no real need to cast.  change arg to match expected class
00546     RemoteAtCommandResponse* at = static_cast<RemoteAtCommandResponse*>(&response);
00547 
00548     // pass pointer array to subclass
00549     at->setFrameData(getFrameData());
00550     setCommon(response);
00551 
00552     at->getRemoteAddress64().setMsb((uint32_t(getFrameData()[1]) << 24) + (uint32_t(getFrameData()[2]) << 16) + (uint16_t(getFrameData()[3]) << 8) + getFrameData()[4]);
00553     at->getRemoteAddress64().setLsb((uint32_t(getFrameData()[5]) << 24) + (uint32_t(getFrameData()[6]) << 16) + (uint16_t(getFrameData()[7]) << 8) + (getFrameData()[8]));
00554 
00555 }
00556 
00557 RxDataResponse::RxDataResponse() : XBeeResponse() {
00558 
00559 }
00560 
00561 uint8_t RxDataResponse::getData(int index) {
00562     return getFrameData()[getDataOffset() + index];
00563 }
00564 
00565 uint8_t* RxDataResponse::getData() {
00566     return getFrameData() + getDataOffset();
00567 }
00568 
00569 FrameIdResponse::FrameIdResponse() {
00570 
00571 }
00572 
00573 uint8_t FrameIdResponse::getFrameId() {
00574     return getFrameData()[0];
00575 }
00576 
00577 
00578 ModemStatusResponse::ModemStatusResponse() {
00579 
00580 }
00581 
00582 uint8_t ModemStatusResponse::getStatus() {
00583     return getFrameData()[0];
00584 }
00585 
00586 void XBeeResponse::getModemStatusResponse(XBeeResponse &modemStatusResponse) {
00587 
00588     ModemStatusResponse* modem = static_cast<ModemStatusResponse*>(&modemStatusResponse);
00589 
00590     // pass pointer array to subclass
00591     modem->setFrameData(getFrameData());
00592     setCommon(modemStatusResponse);
00593 
00594 }
00595 
00596 AtCommandResponse::AtCommandResponse() {
00597 
00598 }
00599 
00600 uint8_t* AtCommandResponse::getCommand() {
00601     return getFrameData() + 1;
00602 }
00603 
00604 uint8_t AtCommandResponse::getStatus() {
00605     return getFrameData()[3];
00606 }
00607 
00608 uint16_t AtCommandResponse::getValueLength() {
00609     return getFrameDataLength() - 4;
00610 }
00611 
00612 uint8_t* AtCommandResponse::getValue() {
00613     if (getValueLength() > 0) {
00614         // value is only included for query commands.  set commands does not return a value
00615         return getFrameData() + 4;
00616     }
00617 
00618     return NULL;
00619 }
00620 
00621 bool AtCommandResponse::isOk() {
00622     return getStatus() == AT_OK;
00623 }
00624 
00625 void XBeeResponse::getAtCommandResponse(XBeeResponse &atCommandResponse) {
00626 
00627     AtCommandResponse* at = static_cast<AtCommandResponse*>(&atCommandResponse);
00628 
00629     // pass pointer array to subclass
00630     at->setFrameData(getFrameData());
00631     setCommon(atCommandResponse);
00632 }
00633 
00634 uint16_t XBeeResponse::getPacketLength() {
00635     return ((uint16_t)_msbLength << 8) + _lsbLength;
00636 }
00637 
00638 uint8_t* XBeeResponse::getFrameData() {
00639     return _frameDataPtr;
00640 }
00641 
00642 void XBeeResponse::setFrameData(uint8_t* frameDataPtr) {
00643     _frameDataPtr = frameDataPtr;
00644 }
00645 
00646 void XBeeResponse::init() {
00647     _complete = false;
00648     _errorCode = NO_ERROR;
00649     _checksum = 0;
00650     _apiId = 0;
00651     _msbLength = 0;
00652     _lsbLength = 0;
00653     _frameLength = 0;
00654 }
00655 
00656 void XBeeResponse::reset() {
00657     init();
00658     _apiId = 0;
00659     _msbLength = 0;
00660     _lsbLength = 0;
00661     _checksum = 0;
00662     _frameLength = 0;
00663 
00664     for (int i = 0; i < MAX_FRAME_DATA_SIZE; i++) {
00665         getFrameData()[i] = 0;
00666     }
00667 }
00668 
00669 void XBee::resetResponse() {
00670     _pos = 0;
00671     _epos = 0;
00672     _rts = false;
00673     _escape = false;
00674     _checksumTotal = 0;
00675     _response.reset();
00676 }
00677 
00678 XBee::XBee(PinName p_tx, PinName p_rx): _xbee(p_tx, p_rx) {
00679     _pos = 0;
00680     _epos = 0;
00681     _rts = false;
00682     _escape = false;
00683     _checksumTotal = 0;
00684     _nextFrameId = 0;
00685 
00686     _response.init();
00687     _response.setFrameData(_responseFrameData);
00688 }
00689 
00690 XBee::XBee(PinName p_tx, PinName p_rx, PinName p_cts, PinName p_rts): _xbee(p_tx, p_rx) {
00691     _pos = 0;
00692     _epos = 0;
00693     _escape = false;
00694     _checksumTotal = 0;
00695     _nextFrameId = 0;
00696 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
00697     if (p_cts == p12) { // CTS (P0_17)
00698         LPC_UART1->MCR |= (1<<7); // CTSEN
00699         LPC_PINCON->PINSEL1 &= ~(3 << 2);
00700         LPC_PINCON->PINSEL1 |= (1 << 2); // UART CTS
00701     }
00702     if (p_rts == P0_22) { // RTS (P0_22)
00703         LPC_UART1->MCR |= (1<<6); // RTSEN
00704         LPC_PINCON->PINSEL1 &= ~(3 << 12);
00705         LPC_PINCON->PINSEL1 |= (1 << 12); // UART RTS
00706         _xbee.attach(this, &XBee::isr_recv, Serial::RxIrq);
00707         _rts = true;
00708     } else {
00709         _rts = false;
00710     }
00711 #elif defined(TARGET_LPC11U24)
00712     if (p_cts == p21) { // CTS (P0_7)
00713         LPC_UART->MCR = (1<<7); // CTSEN
00714         LPC_IOCON->PIO0_7 &= ~0x07;
00715         LPC_IOCON->PIO0_7 |= 0x01; // UART CTS
00716     }
00717     if (p_rts == p22) { // RTS (P0_17)
00718         LPC_UART->MCR = (1<<6); // RTSEN
00719         LPC_IOCON->PIO0_17 &= ~0x07;
00720         LPC_IOCON->PIO0_17 |= 0x01; // UART RTS
00721         _xbee.attach(this, &XBee::isr_recv, Serial::RxIrq);
00722         _rts = true;
00723     } else {
00724         _rts = false;
00725     }
00726 #endif
00727 
00728     _response.init();
00729     _response.setFrameData(_responseFrameData);
00730 }
00731 
00732 uint8_t XBee::getNextFrameId() {
00733 
00734     _nextFrameId++;
00735 
00736     if (_nextFrameId == 0) {
00737         // can't send 0 because that disables status response
00738         _nextFrameId = 1;
00739     }
00740 
00741     return _nextFrameId;
00742 }
00743 
00744 void XBee::begin(long baud) {
00745     _xbee.baud(baud);
00746 }
00747 
00748 /*
00749 void XBee::setSerial(HardwareSerial serial) {
00750     Serial = serial;
00751 }
00752 */
00753 
00754 XBeeResponse& XBee::getResponse() {
00755     return _response;
00756 }
00757 
00758 // TODO how to convert response to proper subclass?
00759 void XBee::getResponse(XBeeResponse &response) {
00760 
00761     response.setMsbLength(_response.getMsbLength());
00762     response.setLsbLength(_response.getLsbLength());
00763     response.setApiId(_response.getApiId());
00764     response.setFrameLength(_response.getFrameDataLength());
00765 
00766     response.setFrameData(_response.getFrameData());
00767 }
00768 
00769 void XBee::readPacketUntilAvailable() {
00770     while (!(getResponse().isAvailable() || getResponse().isError())) {
00771         // read some more
00772         readPacket();
00773     }
00774 }
00775 
00776 bool XBee::readPacket(int timeout) {
00777     Timer t;
00778 
00779     if (timeout < 0) {
00780         return false;
00781     }
00782 
00783 /*
00784     unsigned long start = millis();
00785 
00786     while (int((millis() - start)) < timeout) {
00787 */
00788     t.reset();
00789     t.start();
00790     while (t.read_ms() < timeout) {
00791          readPacket();
00792 
00793          if (getResponse().isAvailable()) {
00794              t.stop();
00795              return true;
00796          } else if (getResponse().isError()) {
00797              t.stop();
00798              return false;
00799          }
00800     }
00801 
00802     DBG("(timeout %d %d)\r\n", _pos, _epos);
00803     // timed out
00804     t.stop();
00805     return false;
00806 }
00807 
00808 void XBee::isr_recv () {
00809     _rxbuf[_rxaddr_w] = _xbee.getc();
00810     _rxaddr_w = (_rxaddr_w + 1) % MAX_RXBUF_SIZE;
00811 }
00812 
00813 int XBee::getbuf () {
00814     int r;
00815     __disable_irq();
00816     r = _rxbuf[_rxaddr_r];
00817     _rxaddr_r = (_rxaddr_r + 1) % MAX_RXBUF_SIZE;
00818     __enable_irq();
00819     return r;
00820 }
00821 
00822 int XBee::bufreadable () {
00823     return _rxaddr_w != _rxaddr_r;
00824 }
00825 
00826 void XBee::readPacket() {
00827     // reset previous response
00828     if (_response.isAvailable() || _response.isError()) {
00829         // discard previous packet and start over
00830         resetResponse();
00831     }
00832     
00833 //    while (_xbee.readable()) {
00834     while ((! _rts && _xbee.readable()) || (_rts && bufreadable())) {
00835 
00836 //        b = _xbee.getc();
00837         if (_rts) {
00838             b = getbuf();
00839         } else {
00840             b = _xbee.getc();
00841         }
00842 
00843         if (_pos > 0 && b == START_BYTE && ATAP == 2) {
00844             // new packet start before previous packeted completed -- discard previous packet and start over
00845             DBG("error: %02x %d %d\r\n", b, _pos, _epos);
00846             _response.setErrorCode(UNEXPECTED_START_BYTE);
00847             return;
00848         }
00849 
00850         if (_pos > 0 && b == ESCAPE) {
00851             if (_xbee.readable()) {
00852 //                b = _xbee.getc();
00853                 if (_rts) {
00854                     b = getbuf();
00855                 } else {
00856                     b = _xbee.getc();
00857                 }
00858                 b = 0x20 ^ b;
00859                 _epos ++;
00860             } else {
00861                 // escape byte.  next byte will be
00862                 _escape = true;
00863                 continue;
00864             }
00865         }
00866         DBG("%02x_", b);
00867 
00868         if (_escape == true) {
00869             b = 0x20 ^ b;
00870             _escape = false;
00871             _epos ++;
00872         }
00873 
00874         // checksum includes all bytes starting with api id
00875         if (_pos >= API_ID_INDEX) {
00876             _checksumTotal+= b;
00877         }
00878 
00879         switch(_pos) {
00880             case 0:
00881                 if (b == START_BYTE) {
00882                     _pos++;
00883                 }
00884 
00885                 break;
00886             case 1:
00887                 // length msb
00888                 _response.setMsbLength(b);
00889                 _pos++;
00890 
00891                 break;
00892             case 2:
00893                 // length lsb
00894                 _response.setLsbLength(b);
00895                 _pos++;
00896 
00897                 break;
00898             case 3:
00899                 _response.setApiId(b);
00900                 _pos++;
00901 
00902                 break;
00903             default:
00904                 // starts at fifth byte
00905 
00906                 if (_pos > MAX_FRAME_DATA_SIZE) {
00907                     // exceed max size.  should never occur
00908                     _response.setErrorCode(PACKET_EXCEEDS_BYTE_ARRAY_LENGTH);
00909                     return;
00910                 }
00911 
00912                 // check if we're at the end of the packet
00913                 // packet length does not include start, length, or checksum bytes, so add 3
00914                 if (_pos == (_response.getPacketLength() + 3)) {
00915 //                if (_pos + _epos == (_response.getPacketLength() + 3)) {
00916                     // verify checksum
00917 
00918                     //std::cout << "read checksum " << static_cast<unsigned int>(b) << " at pos " << static_cast<unsigned int>(_pos) << std::endl;
00919                     if ((_checksumTotal & 0xff) == 0xff) {
00920                         _response.setChecksum(b);
00921                         _response.setAvailable(true);
00922 
00923                         _response.setErrorCode(NO_ERROR);
00924                     } else {
00925                         // checksum failed
00926                         DBG("error: checksum %02x %02x %d %d\r\n", b, _checksumTotal, _pos, _epos);
00927                         _response.setErrorCode(CHECKSUM_FAILURE);
00928                     }
00929 
00930                     // minus 4 because we start after start,msb,lsb,api and up to but not including checksum
00931                     // e.g. if frame was one byte, _pos=4 would be the byte, pos=5 is the checksum, where end stop reading
00932                     _response.setFrameLength(_pos - 4);
00933 
00934                     // reset state vars
00935                     _pos = 0;
00936                     _epos = 0;
00937 
00938                     _checksumTotal = 0;
00939 
00940                     return;
00941                 } else {
00942                     // add to packet array, starting with the fourth byte of the apiFrame
00943                     _response.getFrameData()[_pos - 4] = b;
00944                     _pos++;
00945                 }
00946         }
00947     }
00948 }
00949 
00950 // it's peanut butter jelly time!!
00951 
00952 XBeeRequest::XBeeRequest(uint8_t apiId, uint8_t frameId) {
00953     _apiId = apiId;
00954     _frameId = frameId;
00955 }
00956 
00957 void XBeeRequest::setFrameId(uint8_t frameId) {
00958     _frameId = frameId;
00959 }
00960 
00961 uint8_t XBeeRequest::getFrameId() {
00962     return _frameId;
00963 }
00964 
00965 uint8_t XBeeRequest::getApiId() {
00966     return _apiId;
00967 }
00968 
00969 void XBeeRequest::setApiId(uint8_t apiId) {
00970     _apiId = apiId;
00971 }
00972 
00973 //void XBeeRequest::reset() {
00974 //    _frameId = DEFAULT_FRAME_ID;
00975 //}
00976 
00977 //uint8_t XBeeRequest::getPayloadOffset() {
00978 //    return _payloadOffset;
00979 //}
00980 //
00981 //uint8_t XBeeRequest::setPayloadOffset(uint8_t payloadOffset) {
00982 //    _payloadOffset = payloadOffset;
00983 //}
00984 
00985 
00986 PayloadRequest::PayloadRequest(uint8_t apiId, uint8_t frameId, uint8_t *payload, uint16_t payloadLength) : XBeeRequest(apiId, frameId) {
00987     _payloadPtr = payload;
00988     _payloadLength = payloadLength;
00989 }
00990 
00991 uint8_t* PayloadRequest::getPayload() {
00992     return _payloadPtr;
00993 }
00994 
00995 void PayloadRequest::setPayload(uint8_t* payload) {
00996     _payloadPtr = payload;
00997 }
00998 
00999 uint16_t PayloadRequest::getPayloadLength() {
01000     return _payloadLength;
01001 }
01002 
01003 void PayloadRequest::setPayloadLength(uint16_t payloadLength) {
01004     _payloadLength = payloadLength;
01005 }
01006 
01007 
01008 XBeeAddress::XBeeAddress() {
01009 
01010 }
01011 
01012 XBeeAddress64::XBeeAddress64() : XBeeAddress() {
01013 
01014 }
01015 
01016 XBeeAddress64::XBeeAddress64(uint32_t msb, uint32_t lsb) : XBeeAddress() {
01017     _msb = msb;
01018     _lsb = lsb;
01019 }
01020 
01021 uint32_t XBeeAddress64::getMsb() {
01022     return _msb;
01023 }
01024 
01025 void XBeeAddress64::setMsb(uint32_t msb) {
01026     _msb = msb;
01027 }
01028 
01029 uint32_t XBeeAddress64::getLsb() {
01030     return _lsb;
01031 }
01032 
01033 void XBeeAddress64::setLsb(uint32_t lsb) {
01034     _lsb = lsb;
01035 }
01036 
01037 
01038 #ifdef SERIES_2
01039 
01040 ZBTxRequest::ZBTxRequest() : PayloadRequest(ZB_TX_REQUEST, DEFAULT_FRAME_ID, NULL, 0) {
01041 
01042 }
01043 
01044 ZBTxRequest::ZBTxRequest(XBeeAddress64 &addr64, uint16_t addr16, uint8_t broadcastRadius, uint8_t option, uint8_t *data, uint16_t dataLength, uint8_t frameId): PayloadRequest(ZB_TX_REQUEST, frameId, data, dataLength) {
01045     _addr64 = addr64;
01046     _addr16 = addr16;
01047     _broadcastRadius = broadcastRadius;
01048     _option = option;
01049 }
01050 
01051 ZBTxRequest::ZBTxRequest(XBeeAddress64 &addr64, uint8_t *data, uint16_t dataLength): PayloadRequest(ZB_TX_REQUEST, DEFAULT_FRAME_ID, data, dataLength) {
01052     _addr64 = addr64;
01053     _addr16 = ZB_BROADCAST_ADDRESS;
01054     _broadcastRadius = ZB_BROADCAST_RADIUS_MAX_HOPS;
01055     _option = ZB_TX_UNICAST;
01056 }
01057 
01058 uint8_t ZBTxRequest::getFrameData(uint16_t pos) {
01059     if (pos == 0) {
01060         return (_addr64.getMsb() >> 24) & 0xff;
01061     } else if (pos == 1) {
01062         return (_addr64.getMsb() >> 16) & 0xff;
01063     } else if (pos == 2) {
01064         return (_addr64.getMsb() >> 8) & 0xff;
01065     } else if (pos == 3) {
01066         return _addr64.getMsb() & 0xff;
01067     } else if (pos == 4) {
01068         return (_addr64.getLsb() >> 24) & 0xff;
01069     } else if (pos == 5) {
01070         return  (_addr64.getLsb() >> 16) & 0xff;
01071     } else if (pos == 6) {
01072         return (_addr64.getLsb() >> 8) & 0xff;
01073     } else if (pos == 7) {
01074         return _addr64.getLsb() & 0xff;
01075     } else if (pos == 8) {
01076         return (_addr16 >> 8) & 0xff;
01077     } else if (pos == 9) {
01078         return _addr16 & 0xff;
01079     } else if (pos == 10) {
01080         return _broadcastRadius;
01081     } else if (pos == 11) {
01082         return _option;
01083     } else {
01084         return getPayload()[pos - ZB_TX_API_LENGTH];
01085     }
01086 }
01087 
01088 uint16_t ZBTxRequest::getFrameDataLength() {
01089     return ZB_TX_API_LENGTH + getPayloadLength();
01090 }
01091 
01092 XBeeAddress64& ZBTxRequest::getAddress64() {
01093     return _addr64;
01094 }
01095 
01096 uint16_t ZBTxRequest::getAddress16() {
01097     return _addr16;
01098 }
01099 
01100 uint8_t ZBTxRequest::getBroadcastRadius() {
01101     return _broadcastRadius;
01102 }
01103 
01104 uint8_t ZBTxRequest::getOption() {
01105     return _option;
01106 }
01107 
01108 void ZBTxRequest::setAddress64(XBeeAddress64& addr64) {
01109     _addr64 = addr64;
01110 }
01111 
01112 void ZBTxRequest::setAddress16(uint16_t addr16) {
01113     _addr16 = addr16;
01114 }
01115 
01116 void ZBTxRequest::setBroadcastRadius(uint8_t broadcastRadius) {
01117     _broadcastRadius = broadcastRadius;
01118 }
01119 
01120 void ZBTxRequest::setOption(uint8_t option) {
01121     _option = option;
01122 }
01123 
01124 #endif
01125 
01126 #ifdef SERIES_1
01127 
01128 Tx16Request::Tx16Request() : PayloadRequest(TX_16_REQUEST, DEFAULT_FRAME_ID, NULL, 0) {
01129 
01130 }
01131 
01132 Tx16Request::Tx16Request(uint16_t addr16, uint8_t option, uint8_t *data, uint16_t dataLength, uint8_t frameId) : PayloadRequest(TX_16_REQUEST, frameId, data, dataLength) {
01133     _addr16 = addr16;
01134     _option = option;
01135 }
01136 
01137 Tx16Request::Tx16Request(uint16_t addr16, uint8_t *data, uint16_t dataLength) : PayloadRequest(TX_16_REQUEST, DEFAULT_FRAME_ID, data, dataLength) {
01138     _addr16 = addr16;
01139     _option = ACK_OPTION;
01140 }
01141 
01142 uint8_t Tx16Request::getFrameData(uint16_t pos) {
01143 
01144     if (pos == 0) {
01145         return (_addr16 >> 8) & 0xff;
01146     } else if (pos == 1) {
01147         return _addr16 & 0xff;
01148     } else if (pos == 2) {
01149         return _option;
01150     } else {
01151         return getPayload()[pos - TX_16_API_LENGTH];
01152     }
01153 }
01154 
01155 uint16_t Tx16Request::getFrameDataLength() {
01156     return TX_16_API_LENGTH + getPayloadLength();
01157 }
01158 
01159 uint16_t Tx16Request::getAddress16() {
01160     return _addr16;
01161 }
01162 
01163 void Tx16Request::setAddress16(uint16_t addr16) {
01164     _addr16 = addr16;
01165 }
01166 
01167 uint8_t Tx16Request::getOption() {
01168     return _option;
01169 }
01170 
01171 void Tx16Request::setOption(uint8_t option) {
01172     _option = option;
01173 }
01174 
01175 Tx64Request::Tx64Request() : PayloadRequest(TX_64_REQUEST, DEFAULT_FRAME_ID, NULL, 0) {
01176 
01177 }
01178 
01179 Tx64Request::Tx64Request(XBeeAddress64 &addr64, uint8_t option, uint8_t *data, uint16_t dataLength, uint8_t frameId) : PayloadRequest(TX_64_REQUEST, frameId, data, dataLength) {
01180     _addr64 = addr64;
01181     _option = option;
01182 }
01183 
01184 Tx64Request::Tx64Request(XBeeAddress64 &addr64, uint8_t *data, uint16_t dataLength) : PayloadRequest(TX_64_REQUEST, DEFAULT_FRAME_ID, data, dataLength) {
01185     _addr64 = addr64;
01186     _option = ACK_OPTION;
01187 }
01188 
01189 uint8_t Tx64Request::getFrameData(uint16_t pos) {
01190 
01191     if (pos == 0) {
01192         return (_addr64.getMsb() >> 24) & 0xff;
01193     } else if (pos == 1) {
01194         return (_addr64.getMsb() >> 16) & 0xff;
01195     } else if (pos == 2) {
01196         return (_addr64.getMsb() >> 8) & 0xff;
01197     } else if (pos == 3) {
01198         return _addr64.getMsb() & 0xff;
01199     } else if (pos == 4) {
01200         return (_addr64.getLsb() >> 24) & 0xff;
01201     } else if (pos == 5) {
01202         return (_addr64.getLsb() >> 16) & 0xff;
01203     } else if (pos == 6) {
01204         return(_addr64.getLsb() >> 8) & 0xff;
01205     } else if (pos == 7) {
01206         return _addr64.getLsb() & 0xff;
01207     } else if (pos == 8) {
01208         return _option;
01209     } else {
01210         return getPayload()[pos - TX_64_API_LENGTH];
01211     }
01212 }
01213 
01214 uint16_t Tx64Request::getFrameDataLength() {
01215     return TX_64_API_LENGTH + getPayloadLength();
01216 }
01217 
01218 XBeeAddress64& Tx64Request::getAddress64() {
01219     return _addr64;
01220 }
01221 
01222 void Tx64Request::setAddress64(XBeeAddress64& addr64) {
01223     _addr64 = addr64;
01224 }
01225 
01226 uint8_t Tx64Request::getOption() {
01227     return _option;
01228 }
01229 
01230 void Tx64Request::setOption(uint8_t option) {
01231     _option = option;
01232 }
01233 
01234 #endif
01235 
01236 AtCommandRequest::AtCommandRequest() : XBeeRequest(AT_COMMAND_REQUEST, DEFAULT_FRAME_ID) {
01237     _command = NULL;
01238     clearCommandValue();
01239 }
01240 
01241 AtCommandRequest::AtCommandRequest(uint8_t *command, uint8_t *commandValue, uint8_t commandValueLength) : XBeeRequest(AT_COMMAND_REQUEST, DEFAULT_FRAME_ID) {
01242     _command = command;
01243     _commandValue = commandValue;
01244     _commandValueLength = commandValueLength;
01245 }
01246 
01247 AtCommandRequest::AtCommandRequest(uint8_t *command) : XBeeRequest(AT_COMMAND_REQUEST, DEFAULT_FRAME_ID) {
01248     _command = command;
01249     clearCommandValue();
01250 }
01251 
01252 uint8_t* AtCommandRequest::getCommand() {
01253     return _command;
01254 }
01255 
01256 uint8_t* AtCommandRequest::getCommandValue() {
01257     return _commandValue;
01258 }
01259 
01260 uint8_t AtCommandRequest::getCommandValueLength() {
01261     return _commandValueLength;
01262 }
01263 
01264 void AtCommandRequest::setCommand(uint8_t* command) {
01265     _command = command;
01266 }
01267 
01268 void AtCommandRequest::setCommandValue(uint8_t* value) {
01269     _commandValue = value;
01270 }
01271 
01272 void AtCommandRequest::setCommandValueLength(uint8_t length) {
01273     _commandValueLength = length;
01274 }
01275 
01276 uint8_t AtCommandRequest::getFrameData(uint16_t pos) {
01277 
01278     if (pos == 0) {
01279         return _command[0];
01280     } else if (pos == 1) {
01281         return _command[1];
01282     } else {
01283         return _commandValue[pos - AT_COMMAND_API_LENGTH];
01284     }
01285 }
01286 
01287 void AtCommandRequest::clearCommandValue() {
01288     _commandValue = NULL;
01289     _commandValueLength = 0;
01290 }
01291 
01292 //void AtCommandRequest::reset() {
01293 //     XBeeRequest::reset();
01294 //}
01295 
01296 uint16_t AtCommandRequest::getFrameDataLength() {
01297     // command is 2 byte + length of value
01298     return AT_COMMAND_API_LENGTH + _commandValueLength;
01299 }
01300 
01301 XBeeAddress64 RemoteAtCommandRequest::broadcastAddress64 = XBeeAddress64(0x0, BROADCAST_ADDRESS);
01302 
01303 RemoteAtCommandRequest::RemoteAtCommandRequest() : AtCommandRequest(NULL, NULL, 0) {
01304     _remoteAddress16 = 0;
01305     _applyChanges = false;
01306     setApiId(REMOTE_AT_REQUEST);
01307 }
01308 
01309 RemoteAtCommandRequest::RemoteAtCommandRequest(uint16_t remoteAddress16, uint8_t *command, uint8_t *commandValue, uint8_t commandValueLength) : AtCommandRequest(command, commandValue, commandValueLength) {
01310     _remoteAddress64 = broadcastAddress64;
01311     _remoteAddress16 = remoteAddress16;
01312     _applyChanges = true;
01313     setApiId(REMOTE_AT_REQUEST);
01314 }
01315 
01316 RemoteAtCommandRequest::RemoteAtCommandRequest(uint16_t remoteAddress16, uint8_t *command) : AtCommandRequest(command, NULL, 0) {
01317     _remoteAddress64 = broadcastAddress64;
01318     _remoteAddress16 = remoteAddress16;
01319     _applyChanges = false;
01320     setApiId(REMOTE_AT_REQUEST);
01321 }
01322 
01323 RemoteAtCommandRequest::RemoteAtCommandRequest(XBeeAddress64 &remoteAddress64, uint8_t *command, uint8_t *commandValue, uint8_t commandValueLength) : AtCommandRequest(command, commandValue, commandValueLength) {
01324     _remoteAddress64 = remoteAddress64;
01325     // don't worry.. works for series 1 too!
01326     _remoteAddress16 = ZB_BROADCAST_ADDRESS;
01327     _applyChanges = true;
01328     setApiId(REMOTE_AT_REQUEST);
01329 }
01330 
01331 RemoteAtCommandRequest::RemoteAtCommandRequest(XBeeAddress64 &remoteAddress64, uint8_t *command) : AtCommandRequest(command, NULL, 0) {
01332     _remoteAddress64 = remoteAddress64;
01333     _remoteAddress16 = ZB_BROADCAST_ADDRESS;
01334     _applyChanges = false;
01335     setApiId(REMOTE_AT_REQUEST);
01336 }
01337 
01338 uint16_t RemoteAtCommandRequest::getRemoteAddress16() {
01339     return _remoteAddress16;
01340 }
01341 
01342 void RemoteAtCommandRequest::setRemoteAddress16(uint16_t remoteAddress16) {
01343     _remoteAddress16 = remoteAddress16;
01344 }
01345 
01346 XBeeAddress64& RemoteAtCommandRequest::getRemoteAddress64() {
01347     return _remoteAddress64;
01348 }
01349 
01350 void RemoteAtCommandRequest::setRemoteAddress64(XBeeAddress64 &remoteAddress64) {
01351     _remoteAddress64 = remoteAddress64;
01352 }
01353 
01354 bool RemoteAtCommandRequest::getApplyChanges() {
01355     return _applyChanges;
01356 }
01357 
01358 void RemoteAtCommandRequest::setApplyChanges(bool applyChanges) {
01359     _applyChanges = applyChanges;
01360 }
01361 
01362 
01363 uint8_t RemoteAtCommandRequest::getFrameData(uint16_t pos) {
01364     if (pos == 0) {
01365         return (_remoteAddress64.getMsb() >> 24) & 0xff;
01366     } else if (pos == 1) {
01367         return (_remoteAddress64.getMsb() >> 16) & 0xff;
01368     } else if (pos == 2) {
01369         return (_remoteAddress64.getMsb() >> 8) & 0xff;
01370     } else if (pos == 3) {
01371         return _remoteAddress64.getMsb() & 0xff;
01372     } else if (pos == 4) {
01373         return (_remoteAddress64.getLsb() >> 24) & 0xff;
01374     } else if (pos == 5) {
01375         return (_remoteAddress64.getLsb() >> 16) & 0xff;
01376     } else if (pos == 6) {
01377         return(_remoteAddress64.getLsb() >> 8) & 0xff;
01378     } else if (pos == 7) {
01379         return _remoteAddress64.getLsb() & 0xff;
01380     } else if (pos == 8) {
01381         return (_remoteAddress16 >> 8) & 0xff;
01382     } else if (pos == 9) {
01383         return _remoteAddress16 & 0xff;
01384     } else if (pos == 10) {
01385         return _applyChanges ? 2: 0;
01386     } else if (pos == 11) {
01387         return getCommand()[0];
01388     } else if (pos == 12) {
01389         return getCommand()[1];
01390     } else {
01391         return getCommandValue()[pos - REMOTE_AT_COMMAND_API_LENGTH];
01392     }
01393 }
01394 
01395 uint16_t RemoteAtCommandRequest::getFrameDataLength() {
01396     return REMOTE_AT_COMMAND_API_LENGTH + getCommandValueLength();
01397 }
01398 
01399 
01400 // TODO
01401 //GenericRequest::GenericRequest(uint8_t* frame, uint8_t len, uint8_t apiId): XBeeRequest(apiId, *(frame), len) {
01402 //    _frame = frame;
01403 //}
01404 
01405 void XBee::send(XBeeRequest &request) {
01406     // the new new deal
01407 
01408     sendByte(START_BYTE, false);
01409 
01410     // send length
01411     uint8_t msbLen = ((request.getFrameDataLength() + 2) >> 8) & 0xff;
01412     uint8_t lsbLen = (request.getFrameDataLength() + 2) & 0xff;
01413 
01414     sendByte(msbLen, true);
01415     sendByte(lsbLen, true);
01416 
01417     // api id
01418     sendByte(request.getApiId(), true);
01419     sendByte(request.getFrameId(), true);
01420 
01421     uint8_t checksum = 0;
01422 
01423     // compute checksum, start at api id
01424     checksum+= request.getApiId();
01425     checksum+= request.getFrameId();
01426 
01427     //std::cout << "frame length is " << static_cast<unsigned int>(request.getFrameDataLength()) << std::endl;
01428 
01429     for (int i = 0; i < request.getFrameDataLength(); i++) {
01430 //        std::cout << "sending byte [" << static_cast<unsigned int>(i) << "] " << std::endl;
01431         sendByte(request.getFrameData(i), true);
01432         checksum+= request.getFrameData(i);
01433     }
01434 
01435     // perform 2s complement
01436     checksum = 0xff - checksum;
01437 
01438 //    std::cout << "checksum is " << static_cast<unsigned int>(checksum) << std::endl;
01439 
01440     // send checksum
01441     sendByte(checksum, true);
01442 /*
01443     // send packet
01444     Serial.flush();
01445 */
01446     DBG("\r\n");
01447 }
01448 
01449 void XBee::sendByte(uint8_t b, bool escape) {
01450     if (escape && (b == START_BYTE || b == ESCAPE || b == XON || b == XOFF)) {
01451 //        std::cout << "escaping byte [" << toHexString(b) << "] " << std::endl;
01452         _xbee.putc(ESCAPE);
01453         _xbee.putc(b ^ 0x20);
01454     } else {
01455         _xbee.putc(b);
01456     }
01457     DBG("%02x ", b);
01458 }
01459