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:
Tue Jul 21 20:16:36 2015 +0000
Revision:
20:5d0762aa4680
Parent:
19:783c46b13285
Child:
22:312453862371
Fixed getIPAddress

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 18:9fc7976c7b27 23 serial.baud(115200);
sarahmarshy 18:9fc7976c7b27 24 availableID = new int[5];
sarahmarshy 18:9fc7976c7b27 25 for(int i = 0; i<4; 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 {
sam_grove 11:288c15b80a26 52 return -1;
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 18:9fc7976c7b27 72 int32_t ESP8266Interface::disconnect(void) const
sam_grove 11:288c15b80a26 73 {
sam_grove 11:288c15b80a26 74 return -1;
sam_grove 11:288c15b80a26 75 }
sam_grove 11:288c15b80a26 76
sarahmarshy 18:9fc7976c7b27 77 char *ESP8266Interface::getIPAddress(void)
sarahmarshy 18:9fc7976c7b27 78 {
sarahmarshy 20:5d0762aa4680 79 if (!(atParser.send("AT+CIPSTA?") && atParser.recv("+CIPSTA:\"%[^\"]\"", ip)))
sarahmarshy 18:9fc7976c7b27 80 return NULL;
sarahmarshy 18:9fc7976c7b27 81 return ip;
sarahmarshy 18:9fc7976c7b27 82 }
sarahmarshy 18:9fc7976c7b27 83
sarahmarshy 18:9fc7976c7b27 84 char *ESP8266Interface::getGateway(void) const
sam_grove 11:288c15b80a26 85 {
sam_grove 11:288c15b80a26 86 return 0;
sam_grove 11:288c15b80a26 87 }
sam_grove 11:288c15b80a26 88
sarahmarshy 18:9fc7976c7b27 89 char *ESP8266Interface::getNetworkMask(void) const
sam_grove 11:288c15b80a26 90 {
sam_grove 11:288c15b80a26 91 return 0;
sam_grove 11:288c15b80a26 92 }
sam_grove 11:288c15b80a26 93
sarahmarshy 18:9fc7976c7b27 94 char *ESP8266Interface::getMACAddress(void) const
sam_grove 11:288c15b80a26 95 {
sam_grove 11:288c15b80a26 96 return 0;
sam_grove 11:288c15b80a26 97 }
sam_grove 11:288c15b80a26 98
sarahmarshy 18:9fc7976c7b27 99 int32_t ESP8266Interface::isConnected(void)
sam_grove 11:288c15b80a26 100 {
sarahmarshy 18:9fc7976c7b27 101 return (getIPAddress()==NULL) ? -1 : 0;
sam_grove 11:288c15b80a26 102 }
sam_grove 11:288c15b80a26 103
sarahmarshy 18:9fc7976c7b27 104 SocketInterface *ESP8266Interface::allocateSocket(socket_protocol_t socketProtocol)
sarahmarshy 18:9fc7976c7b27 105 {
sarahmarshy 18:9fc7976c7b27 106 int id = -1;
sarahmarshy 18:9fc7976c7b27 107 uuidCounter += 1;
sarahmarshy 18:9fc7976c7b27 108 //Look through the array of available sockets for an unused ID
sarahmarshy 18:9fc7976c7b27 109 for(int i=0; i<sizeof(availableID); i++){
sarahmarshy 18:9fc7976c7b27 110 if (availableID[i] == -1){
sarahmarshy 18:9fc7976c7b27 111 id = i;
sarahmarshy 18:9fc7976c7b27 112 availableID[i] = uuidCounter;
sarahmarshy 18:9fc7976c7b27 113 break;
sarahmarshy 18:9fc7976c7b27 114 }
sarahmarshy 18:9fc7976c7b27 115 }
sarahmarshy 18:9fc7976c7b27 116 if (id == -1){
sarahmarshy 18:9fc7976c7b27 117 return NULL;//tried to allocate more than the maximum 5 sockets
sarahmarshy 18:9fc7976c7b27 118 }
sarahmarshy 18:9fc7976c7b27 119 ESP8266Socket *socket = new ESP8266Socket(uuidCounter, &atParser, socketProtocol, (uint8_t)id);
sarahmarshy 18:9fc7976c7b27 120 return socket;
sam_grove 11:288c15b80a26 121 }
sam_grove 13:0186e9e35a24 122
sarahmarshy 18:9fc7976c7b27 123 int ESP8266Interface::deallocateSocket(SocketInterface *socket)
bridadan 16:b2f781416464 124 {
sarahmarshy 18:9fc7976c7b27 125 int id = (int)static_cast<ESP8266Socket*>(socket)->getID();
sarahmarshy 18:9fc7976c7b27 126 availableID[id] = -1;
sarahmarshy 18:9fc7976c7b27 127 return id;
bridadan 16:b2f781416464 128 }
bridadan 16:b2f781416464 129
sarahmarshy 18:9fc7976c7b27 130 ESP8266Socket::ESP8266Socket(uint32_t handle, ATParser *atParser, socket_protocol_t type, uint8_t id)
sarahmarshy 18:9fc7976c7b27 131 : _handle(handle), atParser(atParser), _id(id)
sarahmarshy 18:9fc7976c7b27 132 {
sarahmarshy 18:9fc7976c7b27 133 SocketInterface::_type = type;
sarahmarshy 18:9fc7976c7b27 134 }
sarahmarshy 18:9fc7976c7b27 135
sarahmarshy 18:9fc7976c7b27 136 const char *ESP8266Socket::getHostByName(const char *name) const
sam_grove 13:0186e9e35a24 137 {
sam_grove 13:0186e9e35a24 138 return 0;
sam_grove 13:0186e9e35a24 139 }
sam_grove 13:0186e9e35a24 140
sarahmarshy 18:9fc7976c7b27 141 void ESP8266Socket::setAddress(const char* addr)
bridadan 16:b2f781416464 142 {
sarahmarshy 18:9fc7976c7b27 143 _addr = (char*)addr;
sarahmarshy 18:9fc7976c7b27 144 }
sarahmarshy 18:9fc7976c7b27 145
sarahmarshy 18:9fc7976c7b27 146 void ESP8266Socket::setPort(uint16_t port)
sarahmarshy 18:9fc7976c7b27 147 {
sarahmarshy 18:9fc7976c7b27 148 _port = port;
bridadan 16:b2f781416464 149 }
bridadan 16:b2f781416464 150
sarahmarshy 18:9fc7976c7b27 151 void ESP8266Socket::setAddressPort(const char* addr, uint16_t port)
bridadan 16:b2f781416464 152 {
sarahmarshy 18:9fc7976c7b27 153 _addr = (char*)addr;
sarahmarshy 18:9fc7976c7b27 154 _port = port;
bridadan 16:b2f781416464 155 }
bridadan 16:b2f781416464 156
sarahmarshy 18:9fc7976c7b27 157 const char *ESP8266Socket::getAddress(void) const
sarahmarshy 18:9fc7976c7b27 158 {
sarahmarshy 18:9fc7976c7b27 159 return (const char*)_addr;
sarahmarshy 18:9fc7976c7b27 160 }
sarahmarshy 18:9fc7976c7b27 161
sarahmarshy 18:9fc7976c7b27 162 uint16_t ESP8266Socket::getPort(void) const
sarahmarshy 18:9fc7976c7b27 163 {
sarahmarshy 18:9fc7976c7b27 164 return _port;
sarahmarshy 18:9fc7976c7b27 165 }
sarahmarshy 18:9fc7976c7b27 166
sarahmarshy 18:9fc7976c7b27 167
sarahmarshy 18:9fc7976c7b27 168 int32_t ESP8266Socket::bind(uint16_t port) const
sam_grove 13:0186e9e35a24 169 {
sam_grove 13:0186e9e35a24 170 return -1;
sam_grove 13:0186e9e35a24 171 }
sam_grove 13:0186e9e35a24 172
sarahmarshy 18:9fc7976c7b27 173 int32_t ESP8266Socket::listen(void) const
sam_grove 13:0186e9e35a24 174 {
sam_grove 13:0186e9e35a24 175 return -1;
sam_grove 13:0186e9e35a24 176 }
sam_grove 13:0186e9e35a24 177
sarahmarshy 18:9fc7976c7b27 178 int32_t ESP8266Socket::accept() const
sam_grove 13:0186e9e35a24 179 {
sam_grove 13:0186e9e35a24 180 return -1;
sam_grove 13:0186e9e35a24 181 }
sam_grove 13:0186e9e35a24 182
sarahmarshy 18:9fc7976c7b27 183 int32_t ESP8266Socket::open()
sam_grove 13:0186e9e35a24 184 {
sarahmarshy 18:9fc7976c7b27 185 char portstr[5];
sarahmarshy 18:9fc7976c7b27 186 char idstr[2];
sarahmarshy 18:9fc7976c7b27 187 sprintf(idstr,"%d",_id);
sarahmarshy 18:9fc7976c7b27 188 sprintf(portstr, "%d", _port);
sarahmarshy 18:9fc7976c7b27 189
sarahmarshy 18:9fc7976c7b27 190 string sock_type;
sarahmarshy 18:9fc7976c7b27 191 if(_type == SOCK_UDP)
sarahmarshy 18:9fc7976c7b27 192 sock_type = "UDP";
sarahmarshy 18:9fc7976c7b27 193 else if(_type == SOCK_TCP)
sarahmarshy 18:9fc7976c7b27 194 sock_type = "TCP";
sarahmarshy 18:9fc7976c7b27 195 string start_command = "AT+CIPSTART="+(string)idstr+",\""+sock_type+"\",\""+(string)_addr+"\","+(string)portstr;
sarahmarshy 19:783c46b13285 196 if (!(atParser->send(start_command.c_str()) && atParser->recv("OK"))){
sarahmarshy 18:9fc7976c7b27 197 return -1;//opening socket not succesful
sarahmarshy 18:9fc7976c7b27 198 }
sam_grove 13:0186e9e35a24 199 return 0;
sarahmarshy 18:9fc7976c7b27 200
sam_grove 13:0186e9e35a24 201 }
sam_grove 13:0186e9e35a24 202
sarahmarshy 18:9fc7976c7b27 203 int32_t ESP8266Socket::send(const void *data, uint32_t amount, uint32_t timeout_ms)
bridadan 16:b2f781416464 204 {
sarahmarshy 18:9fc7976c7b27 205 char idstr[2];
sarahmarshy 18:9fc7976c7b27 206 sprintf(idstr,"%d",_id);
sarahmarshy 18:9fc7976c7b27 207 char lenstr[5];
sarahmarshy 18:9fc7976c7b27 208 sprintf(lenstr,"%d",(int)amount);
sarahmarshy 18:9fc7976c7b27 209
sarahmarshy 18:9fc7976c7b27 210 atParser->setTimeout((int)timeout_ms);
sarahmarshy 18:9fc7976c7b27 211
sarahmarshy 18:9fc7976c7b27 212 string send_command = "AT+CIPSEND="+(string)idstr+","+(string)lenstr;
sarahmarshy 18:9fc7976c7b27 213 if(!atParser->send(send_command.c_str())){
sarahmarshy 18:9fc7976c7b27 214 return -1;
sarahmarshy 18:9fc7976c7b27 215 }
sarahmarshy 18:9fc7976c7b27 216 atParser->write((char*)data, (int)amount);
bridadan 16:b2f781416464 217 return 0;
bridadan 16:b2f781416464 218 }
bridadan 16:b2f781416464 219
sarahmarshy 18:9fc7976c7b27 220 uint32_t ESP8266Socket::recv(void *data, uint32_t amount, uint32_t timeout_ms)
sam_grove 13:0186e9e35a24 221 {
sarahmarshy 18:9fc7976c7b27 222 atParser->setTimeout((int)timeout_ms);
sarahmarshy 18:9fc7976c7b27 223 int length;
sarahmarshy 19:783c46b13285 224 int id;
sarahmarshy 19:783c46b13285 225 if (!(atParser->recv("+IPD,%d,%d:", &id, &length) &&
sarahmarshy 19:783c46b13285 226 atParser->read((char*)data, length) &&
sarahmarshy 19:783c46b13285 227 atParser->recv("OK"))){
sarahmarshy 19:783c46b13285 228 return false;
sarahmarshy 19:783c46b13285 229 }
sarahmarshy 18:9fc7976c7b27 230 return length;
sam_grove 13:0186e9e35a24 231 }
sam_grove 13:0186e9e35a24 232
sarahmarshy 18:9fc7976c7b27 233 int32_t ESP8266Socket::close() const
sam_grove 13:0186e9e35a24 234 {
sarahmarshy 18:9fc7976c7b27 235 char idstr[2];
sarahmarshy 18:9fc7976c7b27 236 sprintf(idstr,"%d",_id);
sarahmarshy 18:9fc7976c7b27 237 string close_command = "AT+CIPCLOSE="+(string)idstr;
sarahmarshy 18:9fc7976c7b27 238
sarahmarshy 19:783c46b13285 239 if (!(atParser->send(close_command.c_str()) && atParser->recv("OK"))){
sarahmarshy 18:9fc7976c7b27 240 return -1;//opening socket not succesful
sarahmarshy 18:9fc7976c7b27 241 }
sam_grove 13:0186e9e35a24 242 return 0;
sam_grove 13:0186e9e35a24 243 }
sarahmarshy 18:9fc7976c7b27 244 uint8_t ESP8266Socket::getID()
sam_grove 13:0186e9e35a24 245 {
sarahmarshy 18:9fc7976c7b27 246 return _id;
bridadan 16:b2f781416464 247 }