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