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