ban4jp - / XBee_with_SPI

Dependents:   XBeeWiFi_SPI_example

Fork of XBee by Suga koubou

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers XBee.cpp Source File

XBee.cpp

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