Suga koubou / XBee

Description: XBee-mbed library http://mbed.org/users/okini3939/notebook/xbee-mbed/

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 }
00651 
00652 void XBeeResponse::reset() {
00653     init();
00654     _apiId = 0;
00655     _msbLength = 0;
00656     _lsbLength = 0;
00657     _checksum = 0;
00658     _frameLength = 0;
00659 
00660     for (int i = 0; i < MAX_FRAME_DATA_SIZE; i++) {
00661         getFrameData()[i] = 0;
00662     }
00663 }
00664 
00665 void XBee::resetResponse() {
00666     _pos = 0;
00667     _epos = 0;
00668     _escape = false;
00669     _checksumTotal = 0;
00670     _response.reset();
00671 }
00672 
00673 XBee::XBee(PinName p_tx, PinName p_rx): _xbee(p_tx, p_rx) {
00674     _pos = 0;
00675     _epos = 0;
00676     _escape = false;
00677     _checksumTotal = 0;
00678     _nextFrameId = 0;
00679 
00680     _response.init();
00681     _response.setFrameData(_responseFrameData);
00682 }
00683 
00684 XBee::XBee(PinName p_tx, PinName p_rx, PinName p_cts, PinName p_rts): _xbee(p_tx, p_rx) {
00685     _pos = 0;
00686     _epos = 0;
00687     _escape = false;
00688     _checksumTotal = 0;
00689     _nextFrameId = 0;
00690 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
00691     if (p_cts == p12) { // CTS (P0_17)
00692         LPC_UART1->MCR |= (1<<7); // CTSEN
00693         LPC_PINCON->PINSEL1 &= ~(3 << 2);
00694         LPC_PINCON->PINSEL1 |= (1 << 2); // UART CTS
00695     }
00696     if (p_rts == P0_22) { // RTS (P0_22)
00697         LPC_UART1->MCR |= (1<<6); // RTSEN
00698         LPC_PINCON->PINSEL1 &= ~(3 << 12);
00699         LPC_PINCON->PINSEL1 |= (1 << 12); // UART RTS
00700         _xbee.attach(this, &XBee::isr_recv, Serial::RxIrq);
00701         _rts = true;
00702     } else {
00703         _rts = false;
00704     }
00705 #elif defined(TARGET_LPC11U24)
00706     if (p_cts == p21) { // CTS (P0_7)
00707         LPC_UART->MCR = (1<<7); // CTSEN
00708         LPC_IOCON->PIO0_7 &= ~0x07;
00709         LPC_IOCON->PIO0_7 |= 0x01; // UART CTS
00710     }
00711     if (p_rts == p22) { // RTS (P0_17)
00712         LPC_UART->MCR = (1<<6); // RTSEN
00713         LPC_IOCON->PIO0_17 &= ~0x07;
00714         LPC_IOCON->PIO0_17 |= 0x01; // UART RTS
00715         _xbee.attach(this, &XBee::isr_recv, Serial::RxIrq);
00716         _rts = true;
00717     } else {
00718         _rts = false;
00719     }
00720 #endif
00721 
00722     _response.init();
00723     _response.setFrameData(_responseFrameData);
00724 }
00725 
00726 uint8_t XBee::getNextFrameId() {
00727 
00728     _nextFrameId++;
00729 
00730     if (_nextFrameId == 0) {
00731         // can't send 0 because that disables status response
00732         _nextFrameId = 1;
00733     }
00734 
00735     return _nextFrameId;
00736 }
00737 
00738 void XBee::begin(long baud) {
00739     _xbee.baud(baud);
00740 }
00741 
00742 /*
00743 void XBee::setSerial(HardwareSerial serial) {
00744     Serial = serial;
00745 }
00746 */
00747 
00748 XBeeResponse& XBee::getResponse() {
00749     return _response;
00750 }
00751 
00752 // TODO how to convert response to proper subclass?
00753 void XBee::getResponse(XBeeResponse &response) {
00754 
00755     response.setMsbLength(_response.getMsbLength());
00756     response.setLsbLength(_response.getLsbLength());
00757     response.setApiId(_response.getApiId());
00758     response.setFrameLength(_response.getFrameDataLength());
00759 
00760     response.setFrameData(_response.getFrameData());
00761 }
00762 
00763 void XBee::readPacketUntilAvailable() {
00764     while (!(getResponse().isAvailable() || getResponse().isError())) {
00765         // read some more
00766         readPacket();
00767     }
00768 }
00769 
00770 bool XBee::readPacket(int timeout) {
00771     Timer t;
00772 
00773     if (timeout < 0) {
00774         return false;
00775     }
00776 
00777 /*
00778     unsigned long start = millis();
00779 
00780     while (int((millis() - start)) < timeout) {
00781 */
00782     t.reset();
00783     t.start();
00784     while (t.read_ms() < timeout) {
00785          readPacket();
00786 
00787          if (getResponse().isAvailable()) {
00788              t.stop();
00789              return true;
00790          } else if (getResponse().isError()) {
00791              t.stop();
00792              return false;
00793          }
00794     }
00795 
00796     DBG("(timeout %d %d)\r\n", _pos, _epos);
00797     // timed out
00798     t.stop();
00799     return false;
00800 }
00801 
00802 void XBee::isr_recv () {
00803     _rxbuf[_rxaddr_w] = _xbee.getc();
00804     _rxaddr_w = (_rxaddr_w + 1) % MAX_RXBUF_SIZE;
00805 }
00806 
00807 int XBee::getbuf () {
00808     int r;
00809     __disable_irq();
00810     r = _rxbuf[_rxaddr_r];
00811     _rxaddr_r = (_rxaddr_r + 1) % MAX_RXBUF_SIZE;
00812     __enable_irq();
00813     return r;
00814 }
00815 
00816 int XBee::bufreadable () {
00817     return _rxaddr_w != _rxaddr_r;
00818 }
00819 
00820 void XBee::readPacket() {
00821     // reset previous response
00822     if (_response.isAvailable() || _response.isError()) {
00823         // discard previous packet and start over
00824         resetResponse();
00825     }
00826 
00827 //    while (_xbee.readable()) {
00828     while ((! _rts && _xbee.readable()) || (_rts && bufreadable())) {
00829 
00830 //        b = _xbee.getc();
00831         if (_rts) {
00832             b = getbuf();
00833         } else {
00834             b = _xbee.getc();
00835         }
00836 
00837         if (_pos > 0 && b == START_BYTE && ATAP == 2) {
00838             // new packet start before previous packeted completed -- discard previous packet and start over
00839             DBG("error: %02x %d %d\r\n", b, _pos, _epos);
00840             _response.setErrorCode(UNEXPECTED_START_BYTE);
00841             return;
00842         }
00843 
00844         if (_pos > 0 && b == ESCAPE) {
00845             if (_xbee.readable()) {
00846 //                b = _xbee.getc();
00847                 if (_rts) {
00848                     b = getbuf();
00849                 } else {
00850                     b = _xbee.getc();
00851                 }
00852                 b = 0x20 ^ b;
00853                 _epos ++;
00854             } else {
00855                 // escape byte.  next byte will be
00856                 _escape = true;
00857                 continue;
00858             }
00859         }
00860         DBG("%02x_", b);
00861 
00862         if (_escape == true) {
00863             b = 0x20 ^ b;
00864             _escape = false;
00865             _epos ++;
00866         }
00867 
00868         // checksum includes all bytes starting with api id
00869         if (_pos >= API_ID_INDEX) {
00870             _checksumTotal+= b;
00871         }
00872 
00873         switch(_pos) {
00874             case 0:
00875                 if (b == START_BYTE) {
00876                     _pos++;
00877                 }
00878 
00879                 break;
00880             case 1:
00881                 // length msb
00882                 _response.setMsbLength(b);
00883                 _pos++;
00884 
00885                 break;
00886             case 2:
00887                 // length lsb
00888                 _response.setLsbLength(b);
00889                 _pos++;
00890 
00891                 break;
00892             case 3:
00893                 _response.setApiId(b);
00894                 _pos++;
00895 
00896                 break;
00897             default:
00898                 // starts at fifth byte
00899 
00900                 if (_pos > MAX_FRAME_DATA_SIZE) {
00901                     // exceed max size.  should never occur
00902                     _response.setErrorCode(PACKET_EXCEEDS_BYTE_ARRAY_LENGTH);
00903                     return;
00904                 }
00905 
00906                 // check if we're at the end of the packet
00907                 // packet length does not include start, length, or checksum bytes, so add 3
00908                 if (_pos == (_response.getPacketLength() + 3)) {
00909 //                if (_pos + _epos == (_response.getPacketLength() + 3)) {
00910                     // verify checksum
00911 
00912                     //std::cout << "read checksum " << static_cast<unsigned int>(b) << " at pos " << static_cast<unsigned int>(_pos) << std::endl;
00913                     if ((_checksumTotal & 0xff) == 0xff) {
00914                         _response.setChecksum(b);
00915                         _response.setAvailable(true);
00916 
00917                         _response.setErrorCode(NO_ERROR);
00918                     } else {
00919                         // checksum failed
00920                         DBG("error: checksum %02x %02x %d %d\r\n", b, _checksumTotal, _pos, _epos);
00921                         _response.setErrorCode(CHECKSUM_FAILURE);
00922                     }
00923 
00924                     // minus 4 because we start after start,msb,lsb,api and up to but not including checksum
00925                     // e.g. if frame was one byte, _pos=4 would be the byte, pos=5 is the checksum, where end stop reading
00926                     _response.setFrameLength(_pos - 4);
00927 
00928                     // reset state vars
00929                     _pos = 0;
00930                     _epos = 0;
00931 
00932                     _checksumTotal = 0;
00933 
00934                     return;
00935                 } else {
00936                     // add to packet array, starting with the fourth byte of the apiFrame
00937                     _response.getFrameData()[_pos - 4] = b;
00938                     _pos++;
00939                 }
00940         }
00941     }
00942 }
00943 
00944 // it's peanut butter jelly time!!
00945 
00946 XBeeRequest::XBeeRequest(uint8_t apiId, uint8_t frameId) {
00947     _apiId = apiId;
00948     _frameId = frameId;
00949 }
00950 
00951 void XBeeRequest::setFrameId(uint8_t frameId) {
00952     _frameId = frameId;
00953 }
00954 
00955 uint8_t XBeeRequest::getFrameId() {
00956     return _frameId;
00957 }
00958 
00959 uint8_t XBeeRequest::getApiId() {
00960     return _apiId;
00961 }
00962 
00963 void XBeeRequest::setApiId(uint8_t apiId) {
00964     _apiId = apiId;
00965 }
00966 
00967 //void XBeeRequest::reset() {
00968 //    _frameId = DEFAULT_FRAME_ID;
00969 //}
00970 
00971 //uint8_t XBeeRequest::getPayloadOffset() {
00972 //    return _payloadOffset;
00973 //}
00974 //
00975 //uint8_t XBeeRequest::setPayloadOffset(uint8_t payloadOffset) {
00976 //    _payloadOffset = payloadOffset;
00977 //}
00978 
00979 
00980 PayloadRequest::PayloadRequest(uint8_t apiId, uint8_t frameId, uint8_t *payload, uint16_t payloadLength) : XBeeRequest(apiId, frameId) {
00981     _payloadPtr = payload;
00982     _payloadLength = payloadLength;
00983 }
00984 
00985 uint8_t* PayloadRequest::getPayload() {
00986     return _payloadPtr;
00987 }
00988 
00989 void PayloadRequest::setPayload(uint8_t* payload) {
00990     _payloadPtr = payload;
00991 }
00992 
00993 uint16_t PayloadRequest::getPayloadLength() {
00994     return _payloadLength;
00995 }
00996 
00997 void PayloadRequest::setPayloadLength(uint16_t payloadLength) {
00998     _payloadLength = payloadLength;
00999 }
01000 
01001 
01002 XBeeAddress::XBeeAddress() {
01003 
01004 }
01005 
01006 XBeeAddress64::XBeeAddress64() : XBeeAddress() {
01007 
01008 }
01009 
01010 XBeeAddress64::XBeeAddress64(uint32_t msb, uint32_t lsb) : XBeeAddress() {
01011     _msb = msb;
01012     _lsb = lsb;
01013 }
01014 
01015 uint32_t XBeeAddress64::getMsb() {
01016     return _msb;
01017 }
01018 
01019 void XBeeAddress64::setMsb(uint32_t msb) {
01020     _msb = msb;
01021 }
01022 
01023 uint32_t XBeeAddress64::getLsb() {
01024     return _lsb;
01025 }
01026 
01027 void XBeeAddress64::setLsb(uint32_t lsb) {
01028     _lsb = lsb;
01029 }
01030 
01031 
01032 #ifdef SERIES_2
01033 
01034 ZBTxRequest::ZBTxRequest() : PayloadRequest(ZB_TX_REQUEST, DEFAULT_FRAME_ID, NULL, 0) {
01035 
01036 }
01037 
01038 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) {
01039     _addr64 = addr64;
01040     _addr16 = addr16;
01041     _broadcastRadius = broadcastRadius;
01042     _option = option;
01043 }
01044 
01045 ZBTxRequest::ZBTxRequest(XBeeAddress64 &addr64, uint8_t *data, uint16_t dataLength): PayloadRequest(ZB_TX_REQUEST, DEFAULT_FRAME_ID, data, dataLength) {
01046     _addr64 = addr64;
01047     _addr16 = ZB_BROADCAST_ADDRESS;
01048     _broadcastRadius = ZB_BROADCAST_RADIUS_MAX_HOPS;
01049     _option = ZB_TX_UNICAST;
01050 }
01051 
01052 uint8_t ZBTxRequest::getFrameData(uint16_t pos) {
01053     if (pos == 0) {
01054         return (_addr64.getMsb() >> 24) & 0xff;
01055     } else if (pos == 1) {
01056         return (_addr64.getMsb() >> 16) & 0xff;
01057     } else if (pos == 2) {
01058         return (_addr64.getMsb() >> 8) & 0xff;
01059     } else if (pos == 3) {
01060         return _addr64.getMsb() & 0xff;
01061     } else if (pos == 4) {
01062         return (_addr64.getLsb() >> 24) & 0xff;
01063     } else if (pos == 5) {
01064         return  (_addr64.getLsb() >> 16) & 0xff;
01065     } else if (pos == 6) {
01066         return (_addr64.getLsb() >> 8) & 0xff;
01067     } else if (pos == 7) {
01068         return _addr64.getLsb() & 0xff;
01069     } else if (pos == 8) {
01070         return (_addr16 >> 8) & 0xff;
01071     } else if (pos == 9) {
01072         return _addr16 & 0xff;
01073     } else if (pos == 10) {
01074         return _broadcastRadius;
01075     } else if (pos == 11) {
01076         return _option;
01077     } else {
01078         return getPayload()[pos - ZB_TX_API_LENGTH];
01079     }
01080 }
01081 
01082 uint16_t ZBTxRequest::getFrameDataLength() {
01083     return ZB_TX_API_LENGTH + getPayloadLength();
01084 }
01085 
01086 XBeeAddress64& ZBTxRequest::getAddress64() {
01087     return _addr64;
01088 }
01089 
01090 uint16_t ZBTxRequest::getAddress16() {
01091     return _addr16;
01092 }
01093 
01094 uint8_t ZBTxRequest::getBroadcastRadius() {
01095     return _broadcastRadius;
01096 }
01097 
01098 uint8_t ZBTxRequest::getOption() {
01099     return _option;
01100 }
01101 
01102 void ZBTxRequest::setAddress64(XBeeAddress64& addr64) {
01103     _addr64 = addr64;
01104 }
01105 
01106 void ZBTxRequest::setAddress16(uint16_t addr16) {
01107     _addr16 = addr16;
01108 }
01109 
01110 void ZBTxRequest::setBroadcastRadius(uint8_t broadcastRadius) {
01111     _broadcastRadius = broadcastRadius;
01112 }
01113 
01114 void ZBTxRequest::setOption(uint8_t option) {
01115     _option = option;
01116 }
01117 
01118 #endif
01119 
01120 #ifdef SERIES_1
01121 
01122 Tx16Request::Tx16Request() : PayloadRequest(TX_16_REQUEST, DEFAULT_FRAME_ID, NULL, 0) {
01123 
01124 }
01125 
01126 Tx16Request::Tx16Request(uint16_t addr16, uint8_t option, uint8_t *data, uint16_t dataLength, uint8_t frameId) : PayloadRequest(TX_16_REQUEST, frameId, data, dataLength) {
01127     _addr16 = addr16;
01128     _option = option;
01129 }
01130 
01131 Tx16Request::Tx16Request(uint16_t addr16, uint8_t *data, uint16_t dataLength) : PayloadRequest(TX_16_REQUEST, DEFAULT_FRAME_ID, data, dataLength) {
01132     _addr16 = addr16;
01133     _option = ACK_OPTION;
01134 }
01135 
01136 uint8_t Tx16Request::getFrameData(uint16_t pos) {
01137 
01138     if (pos == 0) {
01139         return (_addr16 >> 8) & 0xff;
01140     } else if (pos == 1) {
01141         return _addr16 & 0xff;
01142     } else if (pos == 2) {
01143         return _option;
01144     } else {
01145         return getPayload()[pos - TX_16_API_LENGTH];
01146     }
01147 }
01148 
01149 uint16_t Tx16Request::getFrameDataLength() {
01150     return TX_16_API_LENGTH + getPayloadLength();
01151 }
01152 
01153 uint16_t Tx16Request::getAddress16() {
01154     return _addr16;
01155 }
01156 
01157 void Tx16Request::setAddress16(uint16_t addr16) {
01158     _addr16 = addr16;
01159 }
01160 
01161 uint8_t Tx16Request::getOption() {
01162     return _option;
01163 }
01164 
01165 void Tx16Request::setOption(uint8_t option) {
01166     _option = option;
01167 }
01168 
01169 Tx64Request::Tx64Request() : PayloadRequest(TX_64_REQUEST, DEFAULT_FRAME_ID, NULL, 0) {
01170 
01171 }
01172 
01173 Tx64Request::Tx64Request(XBeeAddress64 &addr64, uint8_t option, uint8_t *data, uint16_t dataLength, uint8_t frameId) : PayloadRequest(TX_64_REQUEST, frameId, data, dataLength) {
01174     _addr64 = addr64;
01175     _option = option;
01176 }
01177 
01178 Tx64Request::Tx64Request(XBeeAddress64 &addr64, uint8_t *data, uint16_t dataLength) : PayloadRequest(TX_64_REQUEST, DEFAULT_FRAME_ID, data, dataLength) {
01179     _addr64 = addr64;
01180     _option = ACK_OPTION;
01181 }
01182 
01183 uint8_t Tx64Request::getFrameData(uint16_t pos) {
01184 
01185     if (pos == 0) {
01186         return (_addr64.getMsb() >> 24) & 0xff;
01187     } else if (pos == 1) {
01188         return (_addr64.getMsb() >> 16) & 0xff;
01189     } else if (pos == 2) {
01190         return (_addr64.getMsb() >> 8) & 0xff;
01191     } else if (pos == 3) {
01192         return _addr64.getMsb() & 0xff;
01193     } else if (pos == 4) {
01194         return (_addr64.getLsb() >> 24) & 0xff;
01195     } else if (pos == 5) {
01196         return (_addr64.getLsb() >> 16) & 0xff;
01197     } else if (pos == 6) {
01198         return(_addr64.getLsb() >> 8) & 0xff;
01199     } else if (pos == 7) {
01200         return _addr64.getLsb() & 0xff;
01201     } else if (pos == 8) {
01202         return _option;
01203     } else {
01204         return getPayload()[pos - TX_64_API_LENGTH];
01205     }
01206 }
01207 
01208 uint16_t Tx64Request::getFrameDataLength() {
01209     return TX_64_API_LENGTH + getPayloadLength();
01210 }
01211 
01212 XBeeAddress64& Tx64Request::getAddress64() {
01213     return _addr64;
01214 }
01215 
01216 void Tx64Request::setAddress64(XBeeAddress64& addr64) {
01217     _addr64 = addr64;
01218 }
01219 
01220 uint8_t Tx64Request::getOption() {
01221     return _option;
01222 }
01223 
01224 void Tx64Request::setOption(uint8_t option) {
01225     _option = option;
01226 }
01227 
01228 #endif
01229 
01230 AtCommandRequest::AtCommandRequest() : XBeeRequest(AT_COMMAND_REQUEST, DEFAULT_FRAME_ID) {
01231     _command = NULL;
01232     clearCommandValue();
01233 }
01234 
01235 AtCommandRequest::AtCommandRequest(uint8_t *command, uint8_t *commandValue, uint8_t commandValueLength) : XBeeRequest(AT_COMMAND_REQUEST, DEFAULT_FRAME_ID) {
01236     _command = command;
01237     _commandValue = commandValue;
01238     _commandValueLength = commandValueLength;
01239 }
01240 
01241 AtCommandRequest::AtCommandRequest(uint8_t *command) : XBeeRequest(AT_COMMAND_REQUEST, DEFAULT_FRAME_ID) {
01242     _command = command;
01243     clearCommandValue();
01244 }
01245 
01246 uint8_t* AtCommandRequest::getCommand() {
01247     return _command;
01248 }
01249 
01250 uint8_t* AtCommandRequest::getCommandValue() {
01251     return _commandValue;
01252 }
01253 
01254 uint8_t AtCommandRequest::getCommandValueLength() {
01255     return _commandValueLength;
01256 }
01257 
01258 void AtCommandRequest::setCommand(uint8_t* command) {
01259     _command = command;
01260 }
01261 
01262 void AtCommandRequest::setCommandValue(uint8_t* value) {
01263     _commandValue = value;
01264 }
01265 
01266 void AtCommandRequest::setCommandValueLength(uint8_t length) {
01267     _commandValueLength = length;
01268 }
01269 
01270 uint8_t AtCommandRequest::getFrameData(uint16_t pos) {
01271 
01272     if (pos == 0) {
01273         return _command[0];
01274     } else if (pos == 1) {
01275         return _command[1];
01276     } else {
01277         return _commandValue[pos - AT_COMMAND_API_LENGTH];
01278     }
01279 }
01280 
01281 void AtCommandRequest::clearCommandValue() {
01282     _commandValue = NULL;
01283     _commandValueLength = 0;
01284 }
01285 
01286 //void AtCommandRequest::reset() {
01287 //     XBeeRequest::reset();
01288 //}
01289 
01290 uint16_t AtCommandRequest::getFrameDataLength() {
01291     // command is 2 byte + length of value
01292     return AT_COMMAND_API_LENGTH + _commandValueLength;
01293 }
01294 
01295 XBeeAddress64 RemoteAtCommandRequest::broadcastAddress64 = XBeeAddress64(0x0, BROADCAST_ADDRESS);
01296 
01297 RemoteAtCommandRequest::RemoteAtCommandRequest() : AtCommandRequest(NULL, NULL, 0) {
01298     _remoteAddress16 = 0;
01299     _applyChanges = false;
01300     setApiId(REMOTE_AT_REQUEST);
01301 }
01302 
01303 RemoteAtCommandRequest::RemoteAtCommandRequest(uint16_t remoteAddress16, uint8_t *command, uint8_t *commandValue, uint8_t commandValueLength) : AtCommandRequest(command, commandValue, commandValueLength) {
01304     _remoteAddress64 = broadcastAddress64;
01305     _remoteAddress16 = remoteAddress16;
01306     _applyChanges = true;
01307     setApiId(REMOTE_AT_REQUEST);
01308 }
01309 
01310 RemoteAtCommandRequest::RemoteAtCommandRequest(uint16_t remoteAddress16, uint8_t *command) : AtCommandRequest(command, NULL, 0) {
01311     _remoteAddress64 = broadcastAddress64;
01312     _remoteAddress16 = remoteAddress16;
01313     _applyChanges = false;
01314     setApiId(REMOTE_AT_REQUEST);
01315 }
01316 
01317 RemoteAtCommandRequest::RemoteAtCommandRequest(XBeeAddress64 &remoteAddress64, uint8_t *command, uint8_t *commandValue, uint8_t commandValueLength) : AtCommandRequest(command, commandValue, commandValueLength) {
01318     _remoteAddress64 = remoteAddress64;
01319     // don't worry.. works for series 1 too!
01320     _remoteAddress16 = ZB_BROADCAST_ADDRESS;
01321     _applyChanges = true;
01322     setApiId(REMOTE_AT_REQUEST);
01323 }
01324 
01325 RemoteAtCommandRequest::RemoteAtCommandRequest(XBeeAddress64 &remoteAddress64, uint8_t *command) : AtCommandRequest(command, NULL, 0) {
01326     _remoteAddress64 = remoteAddress64;
01327     _remoteAddress16 = ZB_BROADCAST_ADDRESS;
01328     _applyChanges = false;
01329     setApiId(REMOTE_AT_REQUEST);
01330 }
01331 
01332 uint16_t RemoteAtCommandRequest::getRemoteAddress16() {
01333     return _remoteAddress16;
01334 }
01335 
01336 void RemoteAtCommandRequest::setRemoteAddress16(uint16_t remoteAddress16) {
01337     _remoteAddress16 = remoteAddress16;
01338 }
01339 
01340 XBeeAddress64& RemoteAtCommandRequest::getRemoteAddress64() {
01341     return _remoteAddress64;
01342 }
01343 
01344 void RemoteAtCommandRequest::setRemoteAddress64(XBeeAddress64 &remoteAddress64) {
01345     _remoteAddress64 = remoteAddress64;
01346 }
01347 
01348 bool RemoteAtCommandRequest::getApplyChanges() {
01349     return _applyChanges;
01350 }
01351 
01352 void RemoteAtCommandRequest::setApplyChanges(bool applyChanges) {
01353     _applyChanges = applyChanges;
01354 }
01355 
01356 
01357 uint8_t RemoteAtCommandRequest::getFrameData(uint16_t pos) {
01358     if (pos == 0) {
01359         return (_remoteAddress64.getMsb() >> 24) & 0xff;
01360     } else if (pos == 1) {
01361         return (_remoteAddress64.getMsb() >> 16) & 0xff;
01362     } else if (pos == 2) {
01363         return (_remoteAddress64.getMsb() >> 8) & 0xff;
01364     } else if (pos == 3) {
01365         return _remoteAddress64.getMsb() & 0xff;
01366     } else if (pos == 4) {
01367         return (_remoteAddress64.getLsb() >> 24) & 0xff;
01368     } else if (pos == 5) {
01369         return (_remoteAddress64.getLsb() >> 16) & 0xff;
01370     } else if (pos == 6) {
01371         return(_remoteAddress64.getLsb() >> 8) & 0xff;
01372     } else if (pos == 7) {
01373         return _remoteAddress64.getLsb() & 0xff;
01374     } else if (pos == 8) {
01375         return (_remoteAddress16 >> 8) & 0xff;
01376     } else if (pos == 9) {
01377         return _remoteAddress16 & 0xff;
01378     } else if (pos == 10) {
01379         return _applyChanges ? 2: 0;
01380     } else if (pos == 11) {
01381         return getCommand()[0];
01382     } else if (pos == 12) {
01383         return getCommand()[1];
01384     } else {
01385         return getCommandValue()[pos - REMOTE_AT_COMMAND_API_LENGTH];
01386     }
01387 }
01388 
01389 uint16_t RemoteAtCommandRequest::getFrameDataLength() {
01390     return REMOTE_AT_COMMAND_API_LENGTH + getCommandValueLength();
01391 }
01392 
01393 
01394 // TODO
01395 //GenericRequest::GenericRequest(uint8_t* frame, uint8_t len, uint8_t apiId): XBeeRequest(apiId, *(frame), len) {
01396 //    _frame = frame;
01397 //}
01398 
01399 void XBee::send(XBeeRequest &request) {
01400     // the new new deal
01401 
01402     sendByte(START_BYTE, false);
01403 
01404     // send length
01405     uint8_t msbLen = ((request.getFrameDataLength() + 2) >> 8) & 0xff;
01406     uint8_t lsbLen = (request.getFrameDataLength() + 2) & 0xff;
01407 
01408     sendByte(msbLen, true);
01409     sendByte(lsbLen, true);
01410 
01411     // api id
01412     sendByte(request.getApiId(), true);
01413     sendByte(request.getFrameId(), true);
01414 
01415     uint8_t checksum = 0;
01416 
01417     // compute checksum, start at api id
01418     checksum+= request.getApiId();
01419     checksum+= request.getFrameId();
01420 
01421     //std::cout << "frame length is " << static_cast<unsigned int>(request.getFrameDataLength()) << std::endl;
01422 
01423     for (int i = 0; i < request.getFrameDataLength(); i++) {
01424 //        std::cout << "sending byte [" << static_cast<unsigned int>(i) << "] " << std::endl;
01425         sendByte(request.getFrameData(i), true);
01426         checksum+= request.getFrameData(i);
01427     }
01428 
01429     // perform 2s complement
01430     checksum = 0xff - checksum;
01431 
01432 //    std::cout << "checksum is " << static_cast<unsigned int>(checksum) << std::endl;
01433 
01434     // send checksum
01435     sendByte(checksum, true);
01436 /*
01437     // send packet
01438     Serial.flush();
01439 */
01440     DBG("\r\n");
01441 }
01442 
01443 void XBee::sendByte(uint8_t b, bool escape) {
01444 
01445     if (escape && (b == START_BYTE || b == ESCAPE || b == XON || b == XOFF)) {
01446 //        std::cout << "escaping byte [" << toHexString(b) << "] " << std::endl;
01447         _xbee.putc(ESCAPE);
01448         _xbee.putc(b ^ 0x20);
01449     } else {
01450         _xbee.putc(b);
01451     }
01452     DBG("%02x ", b);
01453 }
01454