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