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