Xbee API library with support SPI connection. (use only SPI supported model. see also http://www.digi.com/support/kbase/kbaseresultdetl?id=3362 )

Dependents:   XBeeWiFi_SPI_example

Fork of XBee by Suga koubou

Committer:
ban4jp
Date:
Sat Jan 04 15:34:59 2014 +0000
Revision:
10:eb70be6ceb6d
Parent:
9:e32c2e5390d3
Fixed #define USE_XBEE_SPI

Who changed what in which revision?

UserRevisionLine numberNew contents of line
okini3939 2:6efb3541af61 1 /**
okini3939 2:6efb3541af61 2 * XBee Wi-Fi library for mbed
okini3939 2:6efb3541af61 3 * Copyright (c) 2011 Hiroshi Suga
okini3939 2:6efb3541af61 4 * Released under the MIT License: http://mbed.org/license/mit
okini3939 2:6efb3541af61 5 */
okini3939 2:6efb3541af61 6
okini3939 2:6efb3541af61 7 /** @file
okini3939 3:8573b122fa84 8 * @brief XBee Wi-Fi library for mbed
okini3939 2:6efb3541af61 9 */
okini3939 2:6efb3541af61 10
okini3939 6:6f84e2840408 11 #include "XBee_conf.h"
okini3939 6:6f84e2840408 12 #ifdef ENABLE_XBEE_WIFI
okini3939 6:6f84e2840408 13
okini3939 3:8573b122fa84 14 //#define DEBUG
okini3939 3:8573b122fa84 15 #include "dbg.h"
okini3939 3:8573b122fa84 16
okini3939 2:6efb3541af61 17 #include "mbed.h"
okini3939 2:6efb3541af61 18 #include "XBee.h"
okini3939 2:6efb3541af61 19 #include "XBeeWiFi.h"
okini3939 2:6efb3541af61 20 #include "EthernetNetIf.h"
okini3939 2:6efb3541af61 21
okini3939 2:6efb3541af61 22 #define REVERSE_ENDIAN(x) (uint16_t)(((uint16_t)x >> 8) | ((uint16_t)x << 8))
okini3939 2:6efb3541af61 23
ban4jp 10:eb70be6ceb6d 24 #ifndef USE_XBEE_SPI
okini3939 4:f6d73acc1f75 25 XBeeWiFi::XBeeWiFi (PinName p_tx, PinName p_rx, PinName p_cts, PinName p_rts) : XBee(p_tx, p_rx, p_cts, p_rts) {
okini3939 2:6efb3541af61 26 }
ban4jp 9:e32c2e5390d3 27 #endif
ban4jp 9:e32c2e5390d3 28
ban4jp 10:eb70be6ceb6d 29 #ifdef USE_XBEE_SPI
ban4jp 9:e32c2e5390d3 30 XBeeWiFi::XBeeWiFi (PinName p_mosi, PinName p_miso, PinName p_sclk, PinName p_ssel, PinName p_attn, PinName p_reset) :
ban4jp 9:e32c2e5390d3 31 XBee(p_mosi, p_miso, p_sclk, p_ssel, p_attn, p_reset) {
ban4jp 9:e32c2e5390d3 32 }
ban4jp 9:e32c2e5390d3 33 #endif
okini3939 2:6efb3541af61 34
okini3939 2:6efb3541af61 35 int XBeeWiFi::setup (int security, const char *ssid, const char *pin) {
okini3939 3:8573b122fa84 36 int len, r;
okini3939 2:6efb3541af61 37 uint8_t cmd[2], val[32];
okini3939 2:6efb3541af61 38 AtCommandRequest atRequest;
okini3939 2:6efb3541af61 39
okini3939 3:8573b122fa84 40 // SSID
okini3939 3:8573b122fa84 41 memcpy(cmd, "ID", 2);
okini3939 3:8573b122fa84 42 len = strlen(ssid);
okini3939 3:8573b122fa84 43 memcpy(val, ssid, len);
okini3939 3:8573b122fa84 44 atRequest.setCommand(cmd);
okini3939 3:8573b122fa84 45 atRequest.setCommandValue(val);
okini3939 3:8573b122fa84 46 atRequest.setCommandValueLength(len);
okini3939 3:8573b122fa84 47 atRequest.setFrameId(getNextFrameId());
okini3939 3:8573b122fa84 48 send(atRequest);
okini3939 3:8573b122fa84 49 r = getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId());
okini3939 3:8573b122fa84 50 DBG("wifi ID: %d\r\n", r);
okini3939 3:8573b122fa84 51 if (r < 0) return -1;
okini3939 3:8573b122fa84 52
okini3939 3:8573b122fa84 53 if (security != SECURITY_OPEN) {
okini3939 3:8573b122fa84 54 // PIN
okini3939 3:8573b122fa84 55 memcpy(cmd, "PK", 2);
okini3939 3:8573b122fa84 56 len = strlen(pin);
okini3939 3:8573b122fa84 57 memcpy(val, pin, len);
okini3939 3:8573b122fa84 58 atRequest.setCommand(cmd);
okini3939 3:8573b122fa84 59 atRequest.setCommandValue(val);
okini3939 3:8573b122fa84 60 atRequest.setCommandValueLength(len);
okini3939 3:8573b122fa84 61 atRequest.setFrameId(getNextFrameId());
okini3939 3:8573b122fa84 62 send(atRequest);
okini3939 3:8573b122fa84 63 r = getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId());
okini3939 3:8573b122fa84 64 DBG("wifi PK: %d\r\n", r);
okini3939 3:8573b122fa84 65 if (r < 0) return -1;
okini3939 3:8573b122fa84 66 }
okini3939 3:8573b122fa84 67
okini3939 2:6efb3541af61 68 // security type
okini3939 2:6efb3541af61 69 memcpy(cmd, "EE", 2);
okini3939 2:6efb3541af61 70 val[0] = security;
okini3939 2:6efb3541af61 71 atRequest.setCommand(cmd);
okini3939 2:6efb3541af61 72 atRequest.setCommandValue(val);
okini3939 2:6efb3541af61 73 atRequest.setCommandValueLength(1);
okini3939 3:8573b122fa84 74 atRequest.setFrameId(getNextFrameId());
okini3939 2:6efb3541af61 75 send(atRequest);
okini3939 3:8573b122fa84 76 r = getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId());
okini3939 3:8573b122fa84 77 DBG("wifi EE: %d\r\n", r);
okini3939 3:8573b122fa84 78 if (r < 0) return -1;
okini3939 2:6efb3541af61 79
okini3939 2:6efb3541af61 80 return 0;
okini3939 2:6efb3541af61 81 }
okini3939 2:6efb3541af61 82
okini3939 2:6efb3541af61 83 int XBeeWiFi::setup (const char *ssid) {
okini3939 2:6efb3541af61 84 return setup(SECURITY_OPEN, ssid, NULL);
okini3939 2:6efb3541af61 85 }
okini3939 2:6efb3541af61 86
okini3939 2:6efb3541af61 87 int XBeeWiFi::reset () {
okini3939 2:6efb3541af61 88 // RESET
okini3939 3:8573b122fa84 89 uint8_t cmd[2] = {'N', 'R'}; // Network reset
okini3939 3:8573b122fa84 90 // uint8_t cmd[2] = {'F', 'R'}; // Software reset
okini3939 2:6efb3541af61 91 AtCommandRequest atRequest;
okini3939 2:6efb3541af61 92
okini3939 2:6efb3541af61 93 atRequest.setCommand(cmd);
okini3939 3:8573b122fa84 94 atRequest.setFrameId(getNextFrameId());
okini3939 2:6efb3541af61 95 send(atRequest);
okini3939 3:8573b122fa84 96 return getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId());
okini3939 2:6efb3541af61 97 }
okini3939 2:6efb3541af61 98
okini3939 4:f6d73acc1f75 99 int XBeeWiFi::baud (int b) {
okini3939 4:f6d73acc1f75 100 // RESET
okini3939 4:f6d73acc1f75 101 uint8_t cmd[2] = {'B', 'D'};
okini3939 4:f6d73acc1f75 102 char val[4];
okini3939 4:f6d73acc1f75 103 AtCommandRequest atRequest;
okini3939 4:f6d73acc1f75 104 int r, len;
okini3939 4:f6d73acc1f75 105
okini3939 4:f6d73acc1f75 106 if (b < 0x100) {
okini3939 4:f6d73acc1f75 107 val[0] = b;
okini3939 4:f6d73acc1f75 108 len = 1;
okini3939 4:f6d73acc1f75 109 } else {
okini3939 4:f6d73acc1f75 110 val[0] = (b >> 24) & 0xff;
okini3939 4:f6d73acc1f75 111 val[1] = (b >> 16) & 0xff;
okini3939 4:f6d73acc1f75 112 val[2] = (b >> 8) & 0xff;
okini3939 4:f6d73acc1f75 113 val[3] = b & 0xff;
okini3939 4:f6d73acc1f75 114 len = 4;
okini3939 4:f6d73acc1f75 115 }
okini3939 4:f6d73acc1f75 116 atRequest.setCommand(cmd);
okini3939 4:f6d73acc1f75 117 atRequest.setCommandValue((uint8_t*)val);
okini3939 4:f6d73acc1f75 118 atRequest.setCommandValueLength(len);
okini3939 4:f6d73acc1f75 119 atRequest.setFrameId(getNextFrameId());
okini3939 4:f6d73acc1f75 120 send(atRequest);
okini3939 4:f6d73acc1f75 121 r = getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId());
okini3939 4:f6d73acc1f75 122
ban4jp 10:eb70be6ceb6d 123 #ifndef USE_XBEE_SPI
okini3939 4:f6d73acc1f75 124 if (r == 0) {
okini3939 4:f6d73acc1f75 125 begin(b);
okini3939 4:f6d73acc1f75 126 }
ban4jp 9:e32c2e5390d3 127 #endif
okini3939 4:f6d73acc1f75 128 return r;
okini3939 4:f6d73acc1f75 129 }
okini3939 4:f6d73acc1f75 130
okini3939 2:6efb3541af61 131 int XBeeWiFi::setAddress () {
okini3939 2:6efb3541af61 132 // DHCP
okini3939 2:6efb3541af61 133 uint8_t cmd[2] = {'M', 'A'};
okini3939 2:6efb3541af61 134 char val[1] = {0};
okini3939 2:6efb3541af61 135 AtCommandRequest atRequest;
okini3939 2:6efb3541af61 136
okini3939 5:547cfff7adf7 137 _nameserver = IpAddr(0,0,0,0);
okini3939 5:547cfff7adf7 138 _nameport = DNS_PORT;
okini3939 5:547cfff7adf7 139
okini3939 2:6efb3541af61 140 atRequest.setCommand(cmd);
okini3939 2:6efb3541af61 141 atRequest.setCommandValue((uint8_t*)val);
okini3939 2:6efb3541af61 142 atRequest.setCommandValueLength(1);
okini3939 3:8573b122fa84 143 atRequest.setFrameId(getNextFrameId());
okini3939 2:6efb3541af61 144 send(atRequest);
okini3939 2:6efb3541af61 145
okini3939 3:8573b122fa84 146 return getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId());
okini3939 2:6efb3541af61 147 }
okini3939 2:6efb3541af61 148
okini3939 2:6efb3541af61 149 int XBeeWiFi::setAddress (IpAddr &ipaddr, IpAddr &netmask, IpAddr &gateway, IpAddr &nameserver) {
okini3939 2:6efb3541af61 150 uint8_t cmd[2];
okini3939 2:6efb3541af61 151 char val[32];
okini3939 2:6efb3541af61 152 AtCommandRequest atRequest;
okini3939 2:6efb3541af61 153
okini3939 2:6efb3541af61 154 // Static
okini3939 2:6efb3541af61 155 memcpy(cmd, "MA", 2);
okini3939 2:6efb3541af61 156 val[0] = 1;
okini3939 2:6efb3541af61 157 atRequest.setCommand(cmd);
okini3939 2:6efb3541af61 158 atRequest.setCommandValue((uint8_t*)val);
okini3939 2:6efb3541af61 159 atRequest.setCommandValueLength(1);
okini3939 3:8573b122fa84 160 atRequest.setFrameId(getNextFrameId());
okini3939 2:6efb3541af61 161 send(atRequest);
okini3939 3:8573b122fa84 162 getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId());
okini3939 2:6efb3541af61 163
okini3939 2:6efb3541af61 164 // IP address
okini3939 2:6efb3541af61 165 memcpy(cmd, "MY", 2);
okini3939 2:6efb3541af61 166 sprintf(val, "%d.%d.%d.%d", ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]);
okini3939 2:6efb3541af61 167 atRequest.setCommand(cmd);
okini3939 2:6efb3541af61 168 atRequest.setCommandValue((uint8_t*)val);
okini3939 2:6efb3541af61 169 atRequest.setCommandValueLength(strlen(val));
okini3939 3:8573b122fa84 170 atRequest.setFrameId(getNextFrameId());
okini3939 2:6efb3541af61 171 send(atRequest);
okini3939 3:8573b122fa84 172 getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId());
okini3939 2:6efb3541af61 173
okini3939 2:6efb3541af61 174 // sub netmask
okini3939 2:6efb3541af61 175 memcpy(cmd, "NK", 2);
okini3939 2:6efb3541af61 176 sprintf(val, "%d.%d.%d.%d", netmask[0], netmask[1], netmask[2], netmask[3]);
okini3939 2:6efb3541af61 177 atRequest.setCommand(cmd);
okini3939 2:6efb3541af61 178 atRequest.setCommandValue((uint8_t*)val);
okini3939 2:6efb3541af61 179 atRequest.setCommandValueLength(strlen(val));
okini3939 3:8573b122fa84 180 atRequest.setFrameId(getNextFrameId());
okini3939 2:6efb3541af61 181 send(atRequest);
okini3939 3:8573b122fa84 182 getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId());
okini3939 2:6efb3541af61 183
okini3939 2:6efb3541af61 184 // default gateway
okini3939 2:6efb3541af61 185 memcpy(cmd, "GW", 2);
okini3939 2:6efb3541af61 186 sprintf(val, "%d.%d.%d.%d", gateway[0], gateway[1], gateway[2], gateway[3]);
okini3939 2:6efb3541af61 187 atRequest.setCommand(cmd);
okini3939 2:6efb3541af61 188 atRequest.setCommandValue((uint8_t*)val);
okini3939 2:6efb3541af61 189 atRequest.setCommandValueLength(strlen(val));
okini3939 3:8573b122fa84 190 atRequest.setFrameId(getNextFrameId());
okini3939 2:6efb3541af61 191 send(atRequest);
okini3939 3:8573b122fa84 192 getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId());
okini3939 2:6efb3541af61 193
okini3939 2:6efb3541af61 194 // name server
okini3939 2:6efb3541af61 195 _nameserver = nameserver;
okini3939 5:547cfff7adf7 196 _nameport = DNS_PORT;
okini3939 2:6efb3541af61 197
okini3939 2:6efb3541af61 198 return 0;
okini3939 2:6efb3541af61 199 }
okini3939 2:6efb3541af61 200
okini3939 3:8573b122fa84 201 int XBeeWiFi::getAddress (IpAddr &ipaddr, IpAddr &netmask, IpAddr &gateway, IpAddr &nameserver) {
okini3939 3:8573b122fa84 202 int r;
okini3939 3:8573b122fa84 203 uint8_t cmd[2];
okini3939 3:8573b122fa84 204 AtCommandRequest atRequest;
okini3939 3:8573b122fa84 205 AtCommandResponse atResponse;
okini3939 3:8573b122fa84 206
okini3939 3:8573b122fa84 207 memcpy(cmd, "MY", 2);
okini3939 3:8573b122fa84 208 atRequest.setCommand(cmd);
okini3939 3:8573b122fa84 209 atRequest.clearCommandValue();
okini3939 3:8573b122fa84 210 atRequest.setFrameId(getNextFrameId());
okini3939 3:8573b122fa84 211 send(atRequest);
okini3939 3:8573b122fa84 212 r = getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId());
okini3939 3:8573b122fa84 213 DBG("wifi MY: %d\r\n", r);
okini3939 3:8573b122fa84 214 if (r >= 0) {
okini3939 3:8573b122fa84 215 r = getWiAddr(ipaddr);
okini3939 3:8573b122fa84 216 }
okini3939 3:8573b122fa84 217
okini3939 3:8573b122fa84 218 memcpy(cmd, "MK", 2);
okini3939 3:8573b122fa84 219 atRequest.setCommand(cmd);
okini3939 3:8573b122fa84 220 atRequest.clearCommandValue();
okini3939 3:8573b122fa84 221 atRequest.setFrameId(getNextFrameId());
okini3939 3:8573b122fa84 222 send(atRequest);
okini3939 3:8573b122fa84 223 r = getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId());
okini3939 3:8573b122fa84 224 DBG("wifi MK: %d\r\n", r);
okini3939 3:8573b122fa84 225 if (r >= 0) {
okini3939 3:8573b122fa84 226 r = getWiAddr(netmask);
okini3939 3:8573b122fa84 227 }
okini3939 3:8573b122fa84 228
okini3939 3:8573b122fa84 229 memcpy(cmd, "GW", 2);
okini3939 3:8573b122fa84 230 atRequest.setCommand(cmd);
okini3939 3:8573b122fa84 231 atRequest.clearCommandValue();
okini3939 3:8573b122fa84 232 atRequest.setFrameId(getNextFrameId());
okini3939 3:8573b122fa84 233 send(atRequest);
okini3939 3:8573b122fa84 234 r = getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId());
okini3939 3:8573b122fa84 235 DBG("wifi GW: %d\r\n", r);
okini3939 3:8573b122fa84 236 if (r >= 0) {
okini3939 3:8573b122fa84 237 r = getWiAddr(gateway);
okini3939 3:8573b122fa84 238 }
okini3939 3:8573b122fa84 239
okini3939 3:8573b122fa84 240 nameserver = _nameserver;
okini3939 3:8573b122fa84 241
okini3939 3:8573b122fa84 242 return 0;
okini3939 3:8573b122fa84 243 }
okini3939 3:8573b122fa84 244
okini3939 3:8573b122fa84 245 int XBeeWiFi::getWiAddr (IpAddr &ipaddr) {
okini3939 3:8573b122fa84 246 int ip1, ip2, ip3, ip4;
okini3939 3:8573b122fa84 247 AtCommandResponse atResponse;
okini3939 3:8573b122fa84 248
okini3939 3:8573b122fa84 249 getResponse().getAtCommandResponse(atResponse);
okini3939 3:8573b122fa84 250 if (atResponse.isOk() && atResponse.getValueLength() >= 7) {
okini3939 3:8573b122fa84 251 sscanf((char*)atResponse.getValue(), "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
okini3939 3:8573b122fa84 252 ipaddr = IpAddr(ip1, ip2, ip3, ip4);
okini3939 3:8573b122fa84 253 return 0;
okini3939 3:8573b122fa84 254 }
okini3939 3:8573b122fa84 255 return -1;
okini3939 3:8573b122fa84 256 }
okini3939 3:8573b122fa84 257
okini3939 2:6efb3541af61 258 int XBeeWiFi::setTimeout (int timeout) {
okini3939 2:6efb3541af61 259 // timeout
okini3939 2:6efb3541af61 260 uint8_t cmd[2] = {'T', 'P'};
okini3939 2:6efb3541af61 261 char val[1];
okini3939 2:6efb3541af61 262 AtCommandRequest atRequest;
okini3939 2:6efb3541af61 263
okini3939 2:6efb3541af61 264 val[0] = timeout;
okini3939 2:6efb3541af61 265 atRequest.setCommand(cmd);
okini3939 2:6efb3541af61 266 atRequest.setCommandValue((uint8_t*)val);
okini3939 2:6efb3541af61 267 atRequest.setCommandValueLength(1);
okini3939 3:8573b122fa84 268 atRequest.setFrameId(getNextFrameId());
okini3939 2:6efb3541af61 269 send(atRequest);
okini3939 2:6efb3541af61 270
okini3939 2:6efb3541af61 271 return getWiResponse(AT_COMMAND_RESPONSE);
okini3939 2:6efb3541af61 272 }
okini3939 2:6efb3541af61 273
okini3939 2:6efb3541af61 274 int XBeeWiFi::getStatus () {
okini3939 2:6efb3541af61 275 // AI
okini3939 2:6efb3541af61 276 uint8_t cmd[2] = {'A', 'I'};
okini3939 2:6efb3541af61 277 AtCommandRequest atRequest;
okini3939 2:6efb3541af61 278
okini3939 2:6efb3541af61 279 atRequest.setCommand(cmd);
okini3939 3:8573b122fa84 280 atRequest.setFrameId(getNextFrameId());
okini3939 2:6efb3541af61 281 send(atRequest);
okini3939 2:6efb3541af61 282
okini3939 3:8573b122fa84 283 return getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId());
okini3939 2:6efb3541af61 284 }
okini3939 2:6efb3541af61 285
okini3939 3:8573b122fa84 286 int XBeeWiFi::getWiResponse (int apiId, int frameid, int timeout) {
okini3939 2:6efb3541af61 287 AtCommandResponse atResponse;
okini3939 2:6efb3541af61 288
okini3939 2:6efb3541af61 289 if (readPacket(timeout)) {
okini3939 3:8573b122fa84 290 if (frameid && frameid != getResponse().getFrameData()[0]) {
okini3939 3:8573b122fa84 291 DBG("Expected AT response but got %x (frame %d)\r\n", getResponse().getApiId(), getResponse().getFrameData()[0]);
okini3939 3:8573b122fa84 292 if (! readPacket(timeout)) return -1;
okini3939 3:8573b122fa84 293 DBG("Retry ok\r\n");
okini3939 3:8573b122fa84 294 }
okini3939 3:8573b122fa84 295
okini3939 2:6efb3541af61 296 if (getResponse().getApiId() == apiId) {
okini3939 2:6efb3541af61 297 getResponse().getAtCommandResponse(atResponse);
okini3939 2:6efb3541af61 298
okini3939 3:8573b122fa84 299 if (getResponse().getApiId() == IPv4_RX_FRAME) {
okini3939 3:8573b122fa84 300 return 0;
okini3939 3:8573b122fa84 301 } else
okini3939 2:6efb3541af61 302 if (atResponse.isOk()) {
okini3939 2:6efb3541af61 303
okini3939 3:8573b122fa84 304 // if (getResponse().getFrameDataLength() > 4) {
okini3939 2:6efb3541af61 305 return atResponse.getValue()[0];
okini3939 2:6efb3541af61 306
okini3939 2:6efb3541af61 307 } else {
okini3939 3:8573b122fa84 308 DBG("Command return error code: %x\r\n", atResponse.getStatus());
okini3939 2:6efb3541af61 309 }
okini3939 2:6efb3541af61 310 } else {
okini3939 3:8573b122fa84 311 DBG("Expected AT response but got %x\r\n", getResponse().getApiId());
okini3939 2:6efb3541af61 312 }
okini3939 2:6efb3541af61 313 } else {
okini3939 2:6efb3541af61 314 if (getResponse().isError()) {
okini3939 3:8573b122fa84 315 DBG("Error reading packet. Error code: %x\r\n", getResponse().getErrorCode());
okini3939 2:6efb3541af61 316 } else {
okini3939 3:8573b122fa84 317 DBG("No response from radio\r\n");
okini3939 2:6efb3541af61 318 }
okini3939 2:6efb3541af61 319 }
okini3939 2:6efb3541af61 320
okini3939 2:6efb3541af61 321 return -1;
okini3939 2:6efb3541af61 322 }
okini3939 2:6efb3541af61 323
okini3939 2:6efb3541af61 324 #ifdef USE_WIFIDNS
ban4jp 8:dd519c8ac6f7 325 int XBeeWiFi::setNameserver (IpAddr &nameserver, int port) {
okini3939 3:8573b122fa84 326 _nameserver = nameserver;
okini3939 5:547cfff7adf7 327 _nameport = port;
okini3939 3:8573b122fa84 328 return 0;
okini3939 3:8573b122fa84 329 }
okini3939 3:8573b122fa84 330
okini3939 4:f6d73acc1f75 331 // *** Note: wifi is turned off when XBee send the port 53 udp packet.
okini3939 2:6efb3541af61 332 int XBeeWiFi::getHostByName (const char* name, IpAddr &addr) {
okini3939 4:f6d73acc1f75 333 Timer timeout;
okini3939 4:f6d73acc1f75 334 char buf[600];
okini3939 4:f6d73acc1f75 335 int r, len;
okini3939 3:8573b122fa84 336 uint8_t cmd[2] = {'C', '0'};
okini3939 3:8573b122fa84 337 char val[2];
okini3939 2:6efb3541af61 338 IPv4TransmitRequest dnsRequest;
okini3939 2:6efb3541af61 339 AtCommandRequest atRequest;
okini3939 2:6efb3541af61 340 AtCommandResponse atResponse;
okini3939 2:6efb3541af61 341
okini3939 2:6efb3541af61 342 if (!strcmp(name, "localhost")) {
okini3939 2:6efb3541af61 343 addr = IpAddr(127, 0, 0, 1);
okini3939 2:6efb3541af61 344 return 0;
okini3939 2:6efb3541af61 345 }
okini3939 5:547cfff7adf7 346
okini3939 3:8573b122fa84 347 // bind src port
okini3939 3:8573b122fa84 348 val[0] = (DNS_SRC_PORT >> 8) & 0xff;
okini3939 3:8573b122fa84 349 val[1] = DNS_SRC_PORT & 0xff;
okini3939 3:8573b122fa84 350 atRequest.setCommand(cmd);
okini3939 3:8573b122fa84 351 atRequest.setCommandValue((uint8_t*)val);
okini3939 3:8573b122fa84 352 atRequest.setCommandValueLength(2);
okini3939 3:8573b122fa84 353 atRequest.setFrameId(getNextFrameId());
okini3939 3:8573b122fa84 354 send(atRequest);
okini3939 3:8573b122fa84 355 r = getWiResponse(AT_COMMAND_RESPONSE);
okini3939 3:8573b122fa84 356 DBG("wifi C0: %d\r\n", r);
okini3939 5:547cfff7adf7 357
okini3939 2:6efb3541af61 358 // send DNS request
okini3939 3:8573b122fa84 359 len = createDnsRequest(name, buf);
okini3939 2:6efb3541af61 360 dnsRequest.setAddress(_nameserver);
okini3939 5:547cfff7adf7 361 dnsRequest.setDstPort(_nameport);
okini3939 3:8573b122fa84 362 dnsRequest.setSrcPort(DNS_SRC_PORT);
okini3939 2:6efb3541af61 363 dnsRequest.setProtocol(PROTOCOL_UDP);
okini3939 2:6efb3541af61 364 dnsRequest.setPayload((uint8_t*)buf);
okini3939 2:6efb3541af61 365 dnsRequest.setPayloadLength(len);
okini3939 4:f6d73acc1f75 366
okini3939 4:f6d73acc1f75 367 // wait responce
okini3939 4:f6d73acc1f75 368 timeout.reset();
okini3939 4:f6d73acc1f75 369 timeout.start();
okini3939 4:f6d73acc1f75 370 while (timeout.read_ms() < DNS_TIMEOUT) {
okini3939 3:8573b122fa84 371 dnsRequest.setFrameId(getNextFrameId());
okini3939 3:8573b122fa84 372 send(dnsRequest);
okini3939 3:8573b122fa84 373
okini3939 3:8573b122fa84 374 r = getWiResponse(TX_STATUS_RESPONSE, dnsRequest.getFrameId());
okini3939 3:8573b122fa84 375 DBG("wifi TX: %d\r\n", r);
okini3939 2:6efb3541af61 376
okini3939 4:f6d73acc1f75 377 if (r >= 0) {
okini3939 3:8573b122fa84 378 // recv DNS request
okini3939 3:8573b122fa84 379 r = getWiResponse(IPv4_RX_FRAME, 0, 3000);
okini3939 3:8573b122fa84 380 DBG("wifi RX: %d\r\n", r);
okini3939 3:8573b122fa84 381 if (r >= 0) {
okini3939 4:f6d73acc1f75 382 timeout.stop();
okini3939 3:8573b122fa84 383 getResponse().getAtCommandResponse(atResponse);
okini3939 3:8573b122fa84 384 return getDnsResponse(atResponse.getValue() + 6, atResponse.getValueLength() - 6, addr);
okini3939 2:6efb3541af61 385 }
okini3939 3:8573b122fa84 386 } else {
okini3939 3:8573b122fa84 387 break;
okini3939 2:6efb3541af61 388 }
okini3939 2:6efb3541af61 389 }
okini3939 4:f6d73acc1f75 390 timeout.stop();
okini3939 2:6efb3541af61 391
okini3939 2:6efb3541af61 392 return -1;
okini3939 2:6efb3541af61 393 }
okini3939 2:6efb3541af61 394
okini3939 2:6efb3541af61 395 int XBeeWiFi::createDnsRequest (const char* name, char *buf) {
okini3939 2:6efb3541af61 396 struct DNSHeader *dnsHeader;
okini3939 2:6efb3541af61 397 struct DnsQuestionEnd *dnsEnd;
okini3939 2:6efb3541af61 398 int len, num;
okini3939 2:6efb3541af61 399
okini3939 2:6efb3541af61 400 // DNS header
okini3939 2:6efb3541af61 401 dnsHeader = (DNSHeader*)buf;
okini3939 2:6efb3541af61 402 dnsHeader->id = REVERSE_ENDIAN(0xdead);
okini3939 2:6efb3541af61 403 dnsHeader->flags = REVERSE_ENDIAN(0x100);
okini3939 2:6efb3541af61 404 dnsHeader->questions = REVERSE_ENDIAN(1);
okini3939 2:6efb3541af61 405 dnsHeader->answers = 0;
okini3939 2:6efb3541af61 406 dnsHeader->authorities = 0;
okini3939 2:6efb3541af61 407 dnsHeader->additional = 0;
okini3939 2:6efb3541af61 408
okini3939 2:6efb3541af61 409 // DNS question
okini3939 3:8573b122fa84 410 len = sizeof(DNSHeader);
okini3939 3:8573b122fa84 411 while ((num = (int)strchr(name, '.')) != NULL) {
okini3939 2:6efb3541af61 412 num = num - (int)name;
okini3939 2:6efb3541af61 413 buf[len] = num;
okini3939 2:6efb3541af61 414 len ++;
okini3939 2:6efb3541af61 415 strncpy(&buf[len], name, num);
okini3939 3:8573b122fa84 416 name = name + num + 1;
okini3939 2:6efb3541af61 417 len = len + num;
okini3939 2:6efb3541af61 418 }
okini3939 2:6efb3541af61 419
okini3939 3:8573b122fa84 420 if ((num = strlen(name)) != NULL) {
okini3939 2:6efb3541af61 421 buf[len] = num;
okini3939 2:6efb3541af61 422 len ++;
okini3939 2:6efb3541af61 423 strncpy(&buf[len], name, num);
okini3939 3:8573b122fa84 424 len = len + num;
okini3939 2:6efb3541af61 425 }
okini3939 3:8573b122fa84 426 buf[len] = 0;
okini3939 3:8573b122fa84 427 len ++;
okini3939 2:6efb3541af61 428
okini3939 2:6efb3541af61 429 dnsEnd = (DnsQuestionEnd*)&buf[len];
okini3939 2:6efb3541af61 430 dnsEnd->type = REVERSE_ENDIAN(DNS_QUERY_A);
okini3939 2:6efb3541af61 431 dnsEnd->clas = REVERSE_ENDIAN(DNS_CLASS_IN);
okini3939 2:6efb3541af61 432
okini3939 3:8573b122fa84 433 return len + sizeof(DnsQuestionEnd);
okini3939 2:6efb3541af61 434 }
okini3939 2:6efb3541af61 435
okini3939 2:6efb3541af61 436 int XBeeWiFi::getDnsResponse (const uint8_t *buf, int len, IpAddr &addr) {
okini3939 2:6efb3541af61 437 int i;
okini3939 2:6efb3541af61 438 struct DNSHeader *dnsHeader;
okini3939 2:6efb3541af61 439 struct DnsAnswer *dnsAnswer;
okini3939 2:6efb3541af61 440
okini3939 2:6efb3541af61 441 // DNS header
okini3939 2:6efb3541af61 442 dnsHeader = (DNSHeader*)buf;
okini3939 2:6efb3541af61 443 if (REVERSE_ENDIAN(dnsHeader->id) != 0xdead || (REVERSE_ENDIAN(dnsHeader->flags) & 0x800f) != 0x8000) {
okini3939 2:6efb3541af61 444 return -1;
okini3939 2:6efb3541af61 445 }
okini3939 2:6efb3541af61 446
okini3939 2:6efb3541af61 447 // skip question
okini3939 3:8573b122fa84 448 for (i = sizeof(DNSHeader); buf[i] && i < len; i ++);
okini3939 2:6efb3541af61 449 i = i + 1 + sizeof(DnsQuestionEnd);
okini3939 2:6efb3541af61 450
okini3939 2:6efb3541af61 451 // DNS answer
okini3939 2:6efb3541af61 452 while (i < len) {
okini3939 2:6efb3541af61 453 dnsAnswer = (DnsAnswer*)&buf[i];
okini3939 2:6efb3541af61 454 if (dnsAnswer->clas != REVERSE_ENDIAN(DNS_CLASS_IN)) {
okini3939 2:6efb3541af61 455 return -1;
okini3939 2:6efb3541af61 456 }
okini3939 2:6efb3541af61 457
okini3939 3:8573b122fa84 458 i = i + sizeof(DnsAnswer);
okini3939 2:6efb3541af61 459 if (dnsAnswer->type == REVERSE_ENDIAN(DNS_QUERY_A)) {
okini3939 2:6efb3541af61 460 addr = IpAddr(buf[i], buf[i + 1], buf[i + 2], buf[i + 3]);
okini3939 2:6efb3541af61 461 return 0;
okini3939 2:6efb3541af61 462 }
okini3939 2:6efb3541af61 463 i = i + dnsAnswer->length;
okini3939 2:6efb3541af61 464 }
okini3939 2:6efb3541af61 465
okini3939 2:6efb3541af61 466 return -1;
okini3939 2:6efb3541af61 467 }
okini3939 2:6efb3541af61 468 #endif
okini3939 2:6efb3541af61 469
okini3939 2:6efb3541af61 470
okini3939 2:6efb3541af61 471 IPv4TransmitRequest::IPv4TransmitRequest() : PayloadRequest(IPv4_TRANSMIT_REQUEST, DEFAULT_FRAME_ID, NULL, 0) {
okini3939 2:6efb3541af61 472 }
okini3939 2:6efb3541af61 473
okini3939 4:f6d73acc1f75 474 IPv4TransmitRequest::IPv4TransmitRequest(IpAddr &dstAddr, uint16_t dstPort, uint16_t srcPort, uint8_t protocol, uint8_t option, uint8_t *data, uint16_t dataLength, uint8_t frameId): PayloadRequest(IPv4_TRANSMIT_REQUEST, frameId, data, dataLength) {
okini3939 2:6efb3541af61 475 _dstAddr = dstAddr;
okini3939 2:6efb3541af61 476 _dstPort = dstPort;
okini3939 2:6efb3541af61 477 _srcPort = srcPort;
okini3939 2:6efb3541af61 478 _protocol = protocol;
okini3939 2:6efb3541af61 479 _option = option;
okini3939 2:6efb3541af61 480 }
okini3939 2:6efb3541af61 481
okini3939 4:f6d73acc1f75 482 IPv4TransmitRequest::IPv4TransmitRequest(IpAddr &dstAddr, uint16_t dstPort, uint8_t *data, uint16_t dataLength): PayloadRequest(IPv4_TRANSMIT_REQUEST, DEFAULT_FRAME_ID, data, dataLength) {
okini3939 2:6efb3541af61 483 _dstAddr = dstAddr;
okini3939 2:6efb3541af61 484 _dstPort = dstPort;
okini3939 2:6efb3541af61 485 _srcPort = 0x270f;
okini3939 2:6efb3541af61 486 _protocol = PROTOCOL_UDP;
okini3939 2:6efb3541af61 487 _option = 0;
okini3939 2:6efb3541af61 488 }
okini3939 2:6efb3541af61 489
okini3939 4:f6d73acc1f75 490 uint8_t IPv4TransmitRequest::getFrameData(uint16_t pos) {
okini3939 2:6efb3541af61 491 if (pos == 0) {
okini3939 2:6efb3541af61 492 return _dstAddr[0];
okini3939 2:6efb3541af61 493 } else if (pos == 1) {
okini3939 2:6efb3541af61 494 return _dstAddr[1];
okini3939 2:6efb3541af61 495 } else if (pos == 2) {
okini3939 2:6efb3541af61 496 return _dstAddr[2];
okini3939 2:6efb3541af61 497 } else if (pos == 3) {
okini3939 2:6efb3541af61 498 return _dstAddr[3];
okini3939 2:6efb3541af61 499 } else if (pos == 4) {
okini3939 2:6efb3541af61 500 return (_dstPort >> 8) & 0xff;
okini3939 2:6efb3541af61 501 } else if (pos == 5) {
okini3939 2:6efb3541af61 502 return _dstPort & 0xff;
okini3939 2:6efb3541af61 503 } else if (pos == 6) {
okini3939 2:6efb3541af61 504 return (_srcPort >> 8) & 0xff;
okini3939 2:6efb3541af61 505 } else if (pos == 7) {
okini3939 2:6efb3541af61 506 return _srcPort & 0xff;
okini3939 2:6efb3541af61 507 } else if (pos == 8) {
okini3939 2:6efb3541af61 508 return _protocol;
okini3939 2:6efb3541af61 509 } else if (pos == 9) {
okini3939 2:6efb3541af61 510 return _option;
okini3939 2:6efb3541af61 511 } else {
okini3939 2:6efb3541af61 512 return getPayload()[pos - IPv4_TRANSMIT_REQUEST_API_LENGTH];
okini3939 2:6efb3541af61 513 }
okini3939 2:6efb3541af61 514 }
okini3939 2:6efb3541af61 515
okini3939 4:f6d73acc1f75 516 uint16_t IPv4TransmitRequest::getFrameDataLength() {
okini3939 2:6efb3541af61 517 return IPv4_TRANSMIT_REQUEST_API_LENGTH + getPayloadLength();
okini3939 2:6efb3541af61 518 }
okini3939 2:6efb3541af61 519
okini3939 2:6efb3541af61 520 IpAddr& IPv4TransmitRequest::getAddress() {
okini3939 2:6efb3541af61 521 return _dstAddr;
okini3939 2:6efb3541af61 522 }
okini3939 2:6efb3541af61 523
okini3939 2:6efb3541af61 524 uint16_t IPv4TransmitRequest::getDstPort() {
okini3939 2:6efb3541af61 525 return _dstPort;
okini3939 2:6efb3541af61 526 }
okini3939 2:6efb3541af61 527
okini3939 2:6efb3541af61 528 uint16_t IPv4TransmitRequest::getSrcPort() {
okini3939 2:6efb3541af61 529 return _srcPort;
okini3939 2:6efb3541af61 530 }
okini3939 2:6efb3541af61 531
okini3939 2:6efb3541af61 532 uint8_t IPv4TransmitRequest::getProtocol() {
okini3939 2:6efb3541af61 533 return _protocol;
okini3939 2:6efb3541af61 534 }
okini3939 2:6efb3541af61 535
okini3939 2:6efb3541af61 536 uint8_t IPv4TransmitRequest::getOption() {
okini3939 2:6efb3541af61 537 return _option;
okini3939 2:6efb3541af61 538 }
okini3939 2:6efb3541af61 539
okini3939 2:6efb3541af61 540 void IPv4TransmitRequest::setAddress(IpAddr &dstAddr) {
okini3939 2:6efb3541af61 541 _dstAddr = dstAddr;
okini3939 2:6efb3541af61 542 }
okini3939 2:6efb3541af61 543
okini3939 2:6efb3541af61 544 void IPv4TransmitRequest::setDstPort(uint16_t dstPort) {
okini3939 2:6efb3541af61 545 _dstPort = dstPort;
okini3939 2:6efb3541af61 546 }
okini3939 2:6efb3541af61 547
okini3939 2:6efb3541af61 548 void IPv4TransmitRequest::setSrcPort(uint16_t srcPort) {
okini3939 2:6efb3541af61 549 _srcPort = srcPort;
okini3939 2:6efb3541af61 550 }
okini3939 2:6efb3541af61 551
okini3939 2:6efb3541af61 552 void IPv4TransmitRequest::setProtocol(uint8_t protocol) {
okini3939 2:6efb3541af61 553 _protocol = protocol;
okini3939 2:6efb3541af61 554 }
okini3939 2:6efb3541af61 555
okini3939 2:6efb3541af61 556 void IPv4TransmitRequest::setOption(uint8_t option) {
okini3939 2:6efb3541af61 557 _option = option;
okini3939 2:6efb3541af61 558 }
okini3939 2:6efb3541af61 559
okini3939 2:6efb3541af61 560
okini3939 2:6efb3541af61 561 Transmit_Status::Transmit_Status() : FrameIdResponse() {
okini3939 2:6efb3541af61 562
okini3939 2:6efb3541af61 563 }
okini3939 2:6efb3541af61 564
okini3939 2:6efb3541af61 565 uint8_t Transmit_Status::getStatus() {
okini3939 2:6efb3541af61 566 return getFrameData()[1];
okini3939 2:6efb3541af61 567 }
okini3939 2:6efb3541af61 568
okini3939 2:6efb3541af61 569 bool Transmit_Status::isSuccess() {
okini3939 2:6efb3541af61 570 return getStatus() == SUCCESS;
okini3939 2:6efb3541af61 571 }
okini3939 2:6efb3541af61 572
okini3939 2:6efb3541af61 573
okini3939 4:f6d73acc1f75 574 IPV4RxFrame::IPV4RxFrame () {
okini3939 4:f6d73acc1f75 575 }
okini3939 4:f6d73acc1f75 576
okini3939 2:6efb3541af61 577 IpAddr& IPV4RxFrame::getSrcAddress() {
okini3939 4:f6d73acc1f75 578 _srcAddr = IpAddr(getFrameData()[0], getFrameData()[1], getFrameData()[2], getFrameData()[3]);
okini3939 2:6efb3541af61 579 return _srcAddr;
okini3939 2:6efb3541af61 580 }
okini3939 2:6efb3541af61 581
okini3939 2:6efb3541af61 582 uint16_t IPV4RxFrame::getDstPort() {
okini3939 4:f6d73acc1f75 583 return (getFrameData()[4] << 8) + getFrameData()[5];
okini3939 2:6efb3541af61 584 }
okini3939 2:6efb3541af61 585
okini3939 2:6efb3541af61 586 uint16_t IPV4RxFrame::getSrcPort() {
okini3939 4:f6d73acc1f75 587 return (getFrameData()[6] << 8) + getFrameData()[7];
okini3939 2:6efb3541af61 588 }
okini3939 2:6efb3541af61 589
okini3939 2:6efb3541af61 590 uint8_t IPV4RxFrame::getProtocol() {
okini3939 4:f6d73acc1f75 591 return getFrameData()[8];
okini3939 2:6efb3541af61 592 }
okini3939 2:6efb3541af61 593
okini3939 2:6efb3541af61 594 uint8_t IPV4RxFrame::getStatus() {
okini3939 4:f6d73acc1f75 595 return getFrameData()[9];
okini3939 2:6efb3541af61 596 }
okini3939 2:6efb3541af61 597
okini3939 2:6efb3541af61 598 // markers to read data from packet array. this is the index, so the 12th item in the array
okini3939 2:6efb3541af61 599 uint8_t IPV4RxFrame::getDataOffset() {
okini3939 4:f6d73acc1f75 600 return 10;
okini3939 2:6efb3541af61 601 }
okini3939 2:6efb3541af61 602
okini3939 4:f6d73acc1f75 603 uint16_t IPV4RxFrame::getDataLength() {
okini3939 2:6efb3541af61 604 return getPacketLength() - getDataOffset() - 1;
okini3939 2:6efb3541af61 605 }
okini3939 6:6f84e2840408 606
okini3939 6:6f84e2840408 607 #endif
okini3939 6:6f84e2840408 608