Marin Assaliyski / XBee_EA_LPC4088_QS

Dependents:   XBee_WiFi_EA_LPC4088

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