XBee-mbed library http://mbed.org/users/okini3939/notebook/xbee-mbed/
Dependents: device_server_udp led_sender_post XBee_API_ex1 XBee_API_ex2 ... more
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 Tue Jul 12 2022 18:07:39 by 1.7.2