Socket interface for ESP8266. Implements the NetworkSocketAPI. Requires device to use the Espressif Firmware.

Dependencies:   ESP8266

Dependents:   ESP8266InterfaceTests HelloESP8266Interface

Fork of ESP8266Interface by NetworkSocketAPI

Note

This library assumes your ESP8266 is running the Espressif Firmware. For instructions on how to update your ESP8266 to use the correct firmware see the Firmware Update Wiki Page.

Currently the ESP8266Interface LIbrary has the following Abilities:

Working

  • TCP Client
  • UDP Client
  • Transparent mode (single connection of 1 type at a time)
  • Station Mode (connects to AP)

To be implimented

  • TCP Server
  • UDP Server
  • Multi Connection Mode (able to have up to 5 sockets at a time)
  • AP Mode (Make ESP Chip act like access point)
  • DNS Support (currently websites must be looked up by IP)
  • Error Recovery

Nice but not necessary

  • colorized text for ESP AT Commands in Command line (easier to differentiate from other text)
Committer:
sarahmarshy
Date:
Wed Jul 22 20:53:09 2015 +0000
Revision:
22:312453862371
Parent:
20:5d0762aa4680
Child:
23:fd0f3197c30b
Updated socket internals. Implemented getHandle function in ESP8266.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sarahmarshy 18:9fc7976c7b27 1 /* ESP8266Interface Example
sam_grove 11:288c15b80a26 2 * Copyright (c) 2015 ARM Limited
sam_grove 11:288c15b80a26 3 *
sam_grove 11:288c15b80a26 4 * Licensed under the Apache License, Version 2.0 (the "License");
sam_grove 11:288c15b80a26 5 * you may not use this file except in compliance with the License.
sam_grove 11:288c15b80a26 6 * You may obtain a copy of the License at
sam_grove 11:288c15b80a26 7 *
sam_grove 11:288c15b80a26 8 * http://www.apache.org/licenses/LICENSE-2.0
sam_grove 11:288c15b80a26 9 *
sam_grove 11:288c15b80a26 10 * Unless required by applicable law or agreed to in writing, software
sam_grove 11:288c15b80a26 11 * distributed under the License is distributed on an "AS IS" BASIS,
sam_grove 11:288c15b80a26 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
sam_grove 11:288c15b80a26 13 * See the License for the specific language governing permissions and
sam_grove 11:288c15b80a26 14 * limitations under the License.
sam_grove 11:288c15b80a26 15 */
sam_grove 11:288c15b80a26 16
sarahmarshy 18:9fc7976c7b27 17 #include "ESP8266Interface.h"
sarahmarshy 18:9fc7976c7b27 18 #include <string>
sam_grove 11:288c15b80a26 19
sarahmarshy 18:9fc7976c7b27 20 ESP8266Interface::ESP8266Interface(PinName tx, PinName rx)
bridadan 16:b2f781416464 21 : serial(tx, rx), atParser(&serial)
sam_grove 11:288c15b80a26 22 {
sarahmarshy 22:312453862371 23 uuidCounter = 0;
sarahmarshy 18:9fc7976c7b27 24 serial.baud(115200);
sarahmarshy 22:312453862371 25 for(int i = 0; i<numSockets; i++){
sarahmarshy 18:9fc7976c7b27 26 availableID[i] = -1;
sarahmarshy 18:9fc7976c7b27 27 }
sam_grove 11:288c15b80a26 28 }
sam_grove 11:288c15b80a26 29
sarahmarshy 18:9fc7976c7b27 30 ESP8266Interface::ESP8266Interface(PinName tx, PinName rx, const char *ap, const char *pass_phrase, wifi_security_t security, uint32_t timeout_ms)
bridadan 16:b2f781416464 31 : serial(tx, rx), atParser(&serial)
sam_grove 11:288c15b80a26 32 {
sam_grove 11:288c15b80a26 33
sam_grove 11:288c15b80a26 34 }
sam_grove 11:288c15b80a26 35
sarahmarshy 18:9fc7976c7b27 36 int32_t ESP8266Interface::init(void)
sarahmarshy 18:9fc7976c7b27 37 {
sarahmarshy 19:783c46b13285 38 if (!(atParser.send("AT") && atParser.recv("OK")))
sarahmarshy 18:9fc7976c7b27 39 return -1;
sarahmarshy 19:783c46b13285 40 if (!(atParser.send("AT+RST") && atParser.recv("OK\r\nready")))
sarahmarshy 18:9fc7976c7b27 41 return -1;
sarahmarshy 19:783c46b13285 42 if (!(atParser.send("AT+CWMODE=3") && atParser.recv("OK")))
sarahmarshy 18:9fc7976c7b27 43 return -1;
sarahmarshy 19:783c46b13285 44 if (!(atParser.send("AT+CIPMUX=1") && atParser.recv("OK")))
sarahmarshy 18:9fc7976c7b27 45 return -1;
sarahmarshy 18:9fc7976c7b27 46 return 0;
sarahmarshy 18:9fc7976c7b27 47
sam_grove 11:288c15b80a26 48 }
sam_grove 11:288c15b80a26 49
sarahmarshy 18:9fc7976c7b27 50 int32_t ESP8266Interface::init(const char *ip, const char *mask, const char *gateway)
sam_grove 11:288c15b80a26 51 {
sarahmarshy 22:312453862371 52
sam_grove 11:288c15b80a26 53 }
sam_grove 11:288c15b80a26 54
sarahmarshy 18:9fc7976c7b27 55 int32_t ESP8266Interface::connect(uint32_t timeout_ms)
sam_grove 11:288c15b80a26 56 {
sam_grove 11:288c15b80a26 57 return -1;
sam_grove 11:288c15b80a26 58 }
sam_grove 11:288c15b80a26 59
sarahmarshy 18:9fc7976c7b27 60 int32_t ESP8266Interface::connect(const char *ap, const char *pass_phrase, wifi_security_t security, uint32_t timeout_ms)
sam_grove 11:288c15b80a26 61 {
sarahmarshy 19:783c46b13285 62 if (!(atParser.send("AT+CWDHCP=2,1") && atParser.recv("OK")))
sarahmarshy 18:9fc7976c7b27 63 return -1;
sarahmarshy 18:9fc7976c7b27 64 string connect_command = "AT+CWJAP=\""+(string)ap+"\",\""+(string)pass_phrase+"\"";
sarahmarshy 18:9fc7976c7b27 65 atParser.setTimeout(10000);
sarahmarshy 19:783c46b13285 66 if (!(atParser.send(connect_command.c_str()) && atParser.recv("OK"))){
sarahmarshy 18:9fc7976c7b27 67 return -1;
sarahmarshy 18:9fc7976c7b27 68 }
sarahmarshy 18:9fc7976c7b27 69 return 0;
sam_grove 11:288c15b80a26 70 }
sam_grove 11:288c15b80a26 71
sarahmarshy 22:312453862371 72 int32_t ESP8266Interface::disconnect(void)
sam_grove 11:288c15b80a26 73 {
sarahmarshy 22:312453862371 74 if (!(atParser.send("AT+CWQAP") && atParser.recv("OK")))
sarahmarshy 22:312453862371 75 return -1;
sarahmarshy 22:312453862371 76 for(int i=0; i<numSockets; i++){
sarahmarshy 22:312453862371 77 SocketInterface *socket = sockets[availableID[i]];
sarahmarshy 22:312453862371 78 deallocateSocket(socket);
sarahmarshy 22:312453862371 79 }
sarahmarshy 22:312453862371 80 return 0;
sarahmarshy 22:312453862371 81
sam_grove 11:288c15b80a26 82 }
sam_grove 11:288c15b80a26 83
sarahmarshy 18:9fc7976c7b27 84 char *ESP8266Interface::getIPAddress(void)
sarahmarshy 18:9fc7976c7b27 85 {
sarahmarshy 20:5d0762aa4680 86 if (!(atParser.send("AT+CIPSTA?") && atParser.recv("+CIPSTA:\"%[^\"]\"", ip)))
sarahmarshy 18:9fc7976c7b27 87 return NULL;
sarahmarshy 18:9fc7976c7b27 88 return ip;
sarahmarshy 18:9fc7976c7b27 89 }
sarahmarshy 18:9fc7976c7b27 90
sarahmarshy 18:9fc7976c7b27 91 char *ESP8266Interface::getGateway(void) const
sam_grove 11:288c15b80a26 92 {
sam_grove 11:288c15b80a26 93 return 0;
sam_grove 11:288c15b80a26 94 }
sam_grove 11:288c15b80a26 95
sarahmarshy 18:9fc7976c7b27 96 char *ESP8266Interface::getNetworkMask(void) const
sam_grove 11:288c15b80a26 97 {
sam_grove 11:288c15b80a26 98 return 0;
sam_grove 11:288c15b80a26 99 }
sam_grove 11:288c15b80a26 100
sarahmarshy 18:9fc7976c7b27 101 char *ESP8266Interface::getMACAddress(void) const
sam_grove 11:288c15b80a26 102 {
sam_grove 11:288c15b80a26 103 return 0;
sam_grove 11:288c15b80a26 104 }
sam_grove 11:288c15b80a26 105
sarahmarshy 18:9fc7976c7b27 106 int32_t ESP8266Interface::isConnected(void)
sam_grove 11:288c15b80a26 107 {
sarahmarshy 18:9fc7976c7b27 108 return (getIPAddress()==NULL) ? -1 : 0;
sam_grove 11:288c15b80a26 109 }
sam_grove 11:288c15b80a26 110
sarahmarshy 18:9fc7976c7b27 111 SocketInterface *ESP8266Interface::allocateSocket(socket_protocol_t socketProtocol)
sarahmarshy 18:9fc7976c7b27 112 {
sarahmarshy 18:9fc7976c7b27 113 int id = -1;
sarahmarshy 18:9fc7976c7b27 114 //Look through the array of available sockets for an unused ID
sarahmarshy 22:312453862371 115 for(int i=0; i<numSockets; i++){
sarahmarshy 18:9fc7976c7b27 116 if (availableID[i] == -1){
sarahmarshy 18:9fc7976c7b27 117 id = i;
sarahmarshy 18:9fc7976c7b27 118 availableID[i] = uuidCounter;
sarahmarshy 18:9fc7976c7b27 119 break;
sarahmarshy 18:9fc7976c7b27 120 }
sarahmarshy 18:9fc7976c7b27 121 }
sarahmarshy 18:9fc7976c7b27 122 if (id == -1){
sarahmarshy 18:9fc7976c7b27 123 return NULL;//tried to allocate more than the maximum 5 sockets
sarahmarshy 18:9fc7976c7b27 124 }
sarahmarshy 22:312453862371 125 ESP8266Socket *socket = new ESP8266Socket(uuidCounter++, &atParser, socketProtocol, (uint8_t)id);
sarahmarshy 22:312453862371 126 sockets[socket->getHandle()] = socket;
sarahmarshy 18:9fc7976c7b27 127 return socket;
sam_grove 11:288c15b80a26 128 }
sam_grove 13:0186e9e35a24 129
sarahmarshy 18:9fc7976c7b27 130 int ESP8266Interface::deallocateSocket(SocketInterface *socket)
bridadan 16:b2f781416464 131 {
sarahmarshy 18:9fc7976c7b27 132 int id = (int)static_cast<ESP8266Socket*>(socket)->getID();
sarahmarshy 18:9fc7976c7b27 133 availableID[id] = -1;
sarahmarshy 22:312453862371 134
sarahmarshy 22:312453862371 135 std::map<uint32_t, SocketInterface*>::iterator it;
sarahmarshy 22:312453862371 136
sarahmarshy 22:312453862371 137 // Check if socket is owned by WiFiRadioInterface
sarahmarshy 22:312453862371 138 it = sockets.find(socket->getHandle());
sarahmarshy 22:312453862371 139
sarahmarshy 22:312453862371 140 if (it != sockets.end()) {
sarahmarshy 22:312453862371 141 // If so, erase it from the internal socket map and deallocate the socket
sarahmarshy 22:312453862371 142 sockets.erase(it);
sarahmarshy 22:312453862371 143 delete socket;
sarahmarshy 22:312453862371 144 return 0;
sarahmarshy 22:312453862371 145 } else {
sarahmarshy 22:312453862371 146 // Socket is not owned by WiFiRadioInterface, so return -1 error
sarahmarshy 22:312453862371 147 return -1;
sarahmarshy 22:312453862371 148 }
bridadan 16:b2f781416464 149 }
bridadan 16:b2f781416464 150
sarahmarshy 18:9fc7976c7b27 151 ESP8266Socket::ESP8266Socket(uint32_t handle, ATParser *atParser, socket_protocol_t type, uint8_t id)
sarahmarshy 22:312453862371 152 : atParser(atParser), _id(id)
sarahmarshy 18:9fc7976c7b27 153 {
sarahmarshy 22:312453862371 154 _handle = handle;
sarahmarshy 18:9fc7976c7b27 155 SocketInterface::_type = type;
sarahmarshy 18:9fc7976c7b27 156 }
sarahmarshy 18:9fc7976c7b27 157
sarahmarshy 18:9fc7976c7b27 158 const char *ESP8266Socket::getHostByName(const char *name) const
sam_grove 13:0186e9e35a24 159 {
sam_grove 13:0186e9e35a24 160 return 0;
sam_grove 13:0186e9e35a24 161 }
sam_grove 13:0186e9e35a24 162
sarahmarshy 18:9fc7976c7b27 163 void ESP8266Socket::setAddress(const char* addr)
bridadan 16:b2f781416464 164 {
sarahmarshy 18:9fc7976c7b27 165 _addr = (char*)addr;
sarahmarshy 18:9fc7976c7b27 166 }
sarahmarshy 18:9fc7976c7b27 167
sarahmarshy 18:9fc7976c7b27 168 void ESP8266Socket::setPort(uint16_t port)
sarahmarshy 18:9fc7976c7b27 169 {
sarahmarshy 18:9fc7976c7b27 170 _port = port;
bridadan 16:b2f781416464 171 }
bridadan 16:b2f781416464 172
sarahmarshy 18:9fc7976c7b27 173 void ESP8266Socket::setAddressPort(const char* addr, uint16_t port)
bridadan 16:b2f781416464 174 {
sarahmarshy 18:9fc7976c7b27 175 _addr = (char*)addr;
sarahmarshy 18:9fc7976c7b27 176 _port = port;
bridadan 16:b2f781416464 177 }
bridadan 16:b2f781416464 178
sarahmarshy 18:9fc7976c7b27 179 const char *ESP8266Socket::getAddress(void) const
sarahmarshy 18:9fc7976c7b27 180 {
sarahmarshy 18:9fc7976c7b27 181 return (const char*)_addr;
sarahmarshy 18:9fc7976c7b27 182 }
sarahmarshy 18:9fc7976c7b27 183
sarahmarshy 18:9fc7976c7b27 184 uint16_t ESP8266Socket::getPort(void) const
sarahmarshy 18:9fc7976c7b27 185 {
sarahmarshy 18:9fc7976c7b27 186 return _port;
sarahmarshy 18:9fc7976c7b27 187 }
sarahmarshy 18:9fc7976c7b27 188
sarahmarshy 18:9fc7976c7b27 189
sarahmarshy 18:9fc7976c7b27 190 int32_t ESP8266Socket::bind(uint16_t port) const
sam_grove 13:0186e9e35a24 191 {
sam_grove 13:0186e9e35a24 192 return -1;
sam_grove 13:0186e9e35a24 193 }
sam_grove 13:0186e9e35a24 194
sarahmarshy 18:9fc7976c7b27 195 int32_t ESP8266Socket::listen(void) const
sam_grove 13:0186e9e35a24 196 {
sam_grove 13:0186e9e35a24 197 return -1;
sam_grove 13:0186e9e35a24 198 }
sam_grove 13:0186e9e35a24 199
sarahmarshy 18:9fc7976c7b27 200 int32_t ESP8266Socket::accept() const
sam_grove 13:0186e9e35a24 201 {
sam_grove 13:0186e9e35a24 202 return -1;
sam_grove 13:0186e9e35a24 203 }
sam_grove 13:0186e9e35a24 204
sarahmarshy 18:9fc7976c7b27 205 int32_t ESP8266Socket::open()
sam_grove 13:0186e9e35a24 206 {
sarahmarshy 18:9fc7976c7b27 207 char portstr[5];
sarahmarshy 18:9fc7976c7b27 208 char idstr[2];
sarahmarshy 18:9fc7976c7b27 209 sprintf(idstr,"%d",_id);
sarahmarshy 18:9fc7976c7b27 210 sprintf(portstr, "%d", _port);
sarahmarshy 18:9fc7976c7b27 211
sarahmarshy 18:9fc7976c7b27 212 string sock_type;
sarahmarshy 18:9fc7976c7b27 213 if(_type == SOCK_UDP)
sarahmarshy 18:9fc7976c7b27 214 sock_type = "UDP";
sarahmarshy 18:9fc7976c7b27 215 else if(_type == SOCK_TCP)
sarahmarshy 18:9fc7976c7b27 216 sock_type = "TCP";
sarahmarshy 18:9fc7976c7b27 217 string start_command = "AT+CIPSTART="+(string)idstr+",\""+sock_type+"\",\""+(string)_addr+"\","+(string)portstr;
sarahmarshy 19:783c46b13285 218 if (!(atParser->send(start_command.c_str()) && atParser->recv("OK"))){
sarahmarshy 18:9fc7976c7b27 219 return -1;//opening socket not succesful
sarahmarshy 18:9fc7976c7b27 220 }
sam_grove 13:0186e9e35a24 221 return 0;
sarahmarshy 18:9fc7976c7b27 222
sam_grove 13:0186e9e35a24 223 }
sam_grove 13:0186e9e35a24 224
sarahmarshy 18:9fc7976c7b27 225 int32_t ESP8266Socket::send(const void *data, uint32_t amount, uint32_t timeout_ms)
bridadan 16:b2f781416464 226 {
sarahmarshy 18:9fc7976c7b27 227 char idstr[2];
sarahmarshy 18:9fc7976c7b27 228 sprintf(idstr,"%d",_id);
sarahmarshy 18:9fc7976c7b27 229 char lenstr[5];
sarahmarshy 18:9fc7976c7b27 230 sprintf(lenstr,"%d",(int)amount);
sarahmarshy 18:9fc7976c7b27 231
sarahmarshy 18:9fc7976c7b27 232 atParser->setTimeout((int)timeout_ms);
sarahmarshy 18:9fc7976c7b27 233
sarahmarshy 18:9fc7976c7b27 234 string send_command = "AT+CIPSEND="+(string)idstr+","+(string)lenstr;
sarahmarshy 18:9fc7976c7b27 235 if(!atParser->send(send_command.c_str())){
sarahmarshy 18:9fc7976c7b27 236 return -1;
sarahmarshy 18:9fc7976c7b27 237 }
sarahmarshy 18:9fc7976c7b27 238 atParser->write((char*)data, (int)amount);
bridadan 16:b2f781416464 239 return 0;
bridadan 16:b2f781416464 240 }
bridadan 16:b2f781416464 241
sarahmarshy 18:9fc7976c7b27 242 uint32_t ESP8266Socket::recv(void *data, uint32_t amount, uint32_t timeout_ms)
sam_grove 13:0186e9e35a24 243 {
sarahmarshy 18:9fc7976c7b27 244 atParser->setTimeout((int)timeout_ms);
sarahmarshy 18:9fc7976c7b27 245 int length;
sarahmarshy 19:783c46b13285 246 int id;
sarahmarshy 19:783c46b13285 247 if (!(atParser->recv("+IPD,%d,%d:", &id, &length) &&
sarahmarshy 19:783c46b13285 248 atParser->read((char*)data, length) &&
sarahmarshy 19:783c46b13285 249 atParser->recv("OK"))){
sarahmarshy 19:783c46b13285 250 return false;
sarahmarshy 19:783c46b13285 251 }
sarahmarshy 18:9fc7976c7b27 252 return length;
sam_grove 13:0186e9e35a24 253 }
sam_grove 13:0186e9e35a24 254
sarahmarshy 18:9fc7976c7b27 255 int32_t ESP8266Socket::close() const
sam_grove 13:0186e9e35a24 256 {
sarahmarshy 18:9fc7976c7b27 257 char idstr[2];
sarahmarshy 18:9fc7976c7b27 258 sprintf(idstr,"%d",_id);
sarahmarshy 18:9fc7976c7b27 259 string close_command = "AT+CIPCLOSE="+(string)idstr;
sarahmarshy 18:9fc7976c7b27 260
sarahmarshy 19:783c46b13285 261 if (!(atParser->send(close_command.c_str()) && atParser->recv("OK"))){
sarahmarshy 18:9fc7976c7b27 262 return -1;//opening socket not succesful
sarahmarshy 18:9fc7976c7b27 263 }
sam_grove 13:0186e9e35a24 264 return 0;
sam_grove 13:0186e9e35a24 265 }
sarahmarshy 22:312453862371 266
sarahmarshy 22:312453862371 267 uint32_t ESP8266Socket::getHandle()const
sarahmarshy 22:312453862371 268 {
sarahmarshy 22:312453862371 269 return _handle;
sarahmarshy 22:312453862371 270 }
sarahmarshy 22:312453862371 271
sarahmarshy 18:9fc7976c7b27 272 uint8_t ESP8266Socket::getID()
sam_grove 13:0186e9e35a24 273 {
sarahmarshy 18:9fc7976c7b27 274 return _id;
bridadan 16:b2f781416464 275 }