no changes

Fork of XBee by Suga koubou

Committer:
okini3939
Date:
Thu Mar 08 17:41:29 2012 +0000
Revision:
3:8573b122fa84
Parent:
2:6efb3541af61
Child:
4:f6d73acc1f75

        

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