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:
Fri Jul 17 23:15:21 2015 +0000
Revision:
18:9fc7976c7b27
Parent:
WiFiRadioInterface.cpp@16:b2f781416464
Child:
19:783c46b13285
ESP8266 driver implemented on top of NetworkSocketAPI

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