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