XBee API mode library
Diff: Send.cpp
- Revision:
- 0:0232a97b3883
- Child:
- 3:8453df14bd30
diff -r 000000000000 -r 0232a97b3883 Send.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Send.cpp Thu Jul 26 10:33:11 2012 +0000 @@ -0,0 +1,255 @@ +/* +Copyright (c) 2011, Senio Networks, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#include "XBee.h" +#include <stdarg.h> + +void XBee::sendCommand(const char *command, int8_t param, bool queue) { + sendCommand(command, (uint64_t) param, queue); +} + +void XBee::sendCommand(const char *command, int16_t param, bool queue) { + sendCommand(command, (uint64_t) param, queue); +} + +void XBee::sendCommand(const char *command, int32_t param, bool queue) { + sendCommand(command, (uint64_t) param, queue); +} + +void XBee::sendCommand(const char *command, int64_t param, bool queue) { + sendCommand(command, (uint64_t) param, queue); +} + +void XBee::sendCommand(const char *command, uint8_t param, bool queue) { + sendCommand(command, (uint64_t) param, queue); +} + +void XBee::sendCommand(const char *command, uint16_t param, bool queue) { + sendCommand(command, (uint64_t) param, queue); +} + +void XBee::sendCommand(const char *command, uint32_t param, bool queue) { + sendCommand(command, (uint64_t) param, queue); +} + +void XBee::sendCommand(const char *command, uint64_t param, bool queue) { + uint8_t param_buf[8] = { + (uint8_t) (param >> 56), (uint8_t) (param >> 48), + (uint8_t) (param >> 40), (uint8_t) (param >> 32), + (uint8_t) (param >> 24), (uint8_t) (param >> 16), + (uint8_t) (param >> 8), (uint8_t) param + }; + + int n = 0; + while (n < 7 && param_buf[n] == 0) n++; + + sendCommand(command, param_buf + n, 8 - n, queue); +} + +void XBee::sendCommand(const char *command, const char *param, bool queue) { + sendCommand(command, (uint8_t *) param, strlen(param), queue); +} + +void XBee::sendCommand(const char *command, const uint8_t *param, int param_length, bool queue) { + char buf[param_length + 4]; + + createAtRequest(frame_id, command, param, param_length, queue, buf, sizeof(buf)); + sendFrame(buf, param_length + 4); + frame_id = frame_id % 255 + 1; +} + +void XBee::sendRemoteCommand(const char *command, int8_t param) { + sendRemoteCommand(command, (uint64_t) param); +} + +void XBee::sendRemoteCommand(const char *command, int16_t param) { + sendRemoteCommand(command, (uint64_t) param); +} + +void XBee::sendRemoteCommand(const char *command, int32_t param) { + sendRemoteCommand(command, (uint64_t) param); +} + +void XBee::sendRemoteCommand(const char *command, int64_t param) { + sendRemoteCommand(command, (uint64_t) param); +} + +void XBee::sendRemoteCommand(const char *command, uint8_t param) { + sendRemoteCommand(command, (uint64_t) param); +} + +void XBee::sendRemoteCommand(const char *command, uint16_t param) { + sendRemoteCommand(command, (uint64_t) param); +} + +void XBee::sendRemoteCommand(const char *command, uint32_t param) { + sendRemoteCommand(command, (uint64_t) param); +} + +void XBee::sendRemoteCommand(const char *command, uint64_t param) { + uint8_t param_buf[8] = { + (uint8_t) (param >> 56), (uint8_t) (param >> 48), + (uint8_t) (param >> 40), (uint8_t) (param >> 32), + (uint8_t) (param >> 24), (uint8_t) (param >> 16), + (uint8_t) (param >> 8), (uint8_t) param + }; + + int n = 0; + while (n < 7 && param_buf[n] == 0) n++; + + sendRemoteCommand(command, param_buf + n, 8 - n); +} + +void XBee::sendRemoteCommand(const char *command, const char *param) { + sendRemoteCommand(command, (uint8_t *) param, strlen(param)); +} + +void XBee::sendRemoteCommand(const char *command, const uint8_t *param, int param_length, char options) { + char buf[param_length + 15]; + + createRemoteAtRequest(frame_id, command, param, param_length, options, buf, sizeof(buf)); + sendFrame(buf, param_length + 15); + frame_id = frame_id % 255 + 1; +} + +bool XBee::send(const char *data, int length, bool confirm = true) { + if (length == 0) + length = strlen(data); + + char buf[length + 14]; + + createTxRequest(frame_id, data, length, buf, sizeof(buf)); + sendFrame(buf, length + 14); + frame_id = frame_id % 255 + 1; + + if (confirm) { + int index = seekFor(ZigBeeTransmitStatus, 3.0); + if (index != -1) { + char delivery; + scan(index, DeliveryStatus, &delivery); + buf[INDEX(index + 2)] = 0x00; + return delivery == 0; + } + } + + return false; +} + +bool XBee::sendConfirm(const char *data, int length) { + return send(data, length, true); +} + +int XBee::printf(const char *format, ...) { + va_list argv; + va_start(argv, format); + char buf[256]; + int length = vsnprintf(buf, sizeof buf, format, argv); + return length > 0 && sendConfirm(buf, length) ? length : -1; +} + +void XBee::send(char c) { + while (!writeable()) wait_us(100); + putc(c); +} + +void XBee::send2(char c) { + switch (c) { + case 0x7E: + case 0x7D: + case 0x11: + case 0x13: + send(ESCAPE); + send(c ^ 0x20); + break; + default: + send(c); + } +} + +void XBee::sendFrame(const char *frame, int length) { + char checksum = 255; + if (debug) leds = leds | 8; //**LEDS=1xxx + + send(PREAMBLE); + + if (apiMode == 2) { + send2((length >> 8) & 255); + send2(length & 255); + for (int i = 0; i < length; i++) { + send2(frame[i]); + checksum -= frame[i]; + } + send2(checksum); + } else { + send((length >> 8) & 255); + send(length & 255); + for (int i = 0; i < length; i++) { + send(frame[i]); + checksum -= frame[i]; + } + send(checksum); + } + if (debug) leds = leds & 7; //**LEDS=0xxx +} + +int XBee::createTxRequest(char frame_id, const char *data, int data_length, char *buf, int buf_size) { + if (data_length + 14 > buf_size) return -1; + + buf[0] = 0x10; // frame type + buf[1] = frame_id; + for (int i = 0; i < 8; i++) buf[i + 2] = destination64[i]; + buf[10] = destination16[0]; // 16 bit dest address + buf[11] = destination16[1]; // 16 bit dest address + buf[12] = 0; + buf[13] = 0; + for (int i = 0; i < data_length; i++) buf[i + 14] = data[i]; + + return data_length + 14; +} + +int XBee::createAtRequest(char frame_id, const char *command, const uint8_t *param, int param_length, bool queue, char *buf, int buf_size) { + if (param_length + 4 > buf_size) return -1; + + buf[0] = queue ? 0x09 : 0x08; // frame type + buf[1] = frame_id; + buf[2] = command[0]; + buf[3] = command[1]; + for (int i = 0; i < param_length; i++) buf[i + 4] = param[i]; + + return param_length + 4; +} + +int XBee::createRemoteAtRequest(char frame_id, const char *command, const uint8_t *param, int param_length, char options, char *buf, int buf_size) { + if (param_length + 4 > buf_size) return -1; + + buf[0] = 0x17; // frame type + buf[1] = frame_id; + memcpy(buf + 2, destination64, 8); + buf[10] = destination16[0]; + buf[11] = destination16[1]; + buf[12] = options; + buf[13] = command[0]; + buf[14] = command[1]; + for (int i = 0; i < param_length; i++) buf[i + 15] = param[i]; + + return param_length + 15; +} \ No newline at end of file