John Bailey / XBee

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