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

Dependents:   device_server_udp led_sender_post XBee_API_ex1 XBee_API_ex2 ... more

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