/* * This file is part of Espruino, a JavaScript interpreter for Microcontrollers * * Copyright (C) 2013 Gordon Williams * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * ---------------------------------------------------------------------------- * Implementation of JsNetwork for ESP8266 devices * ---------------------------------------------------------------------------- */ #include "jsinteractive.h" #include "network.h" #include "network_esp8266.h" #define INVALID_SOCKET ((SOCKET)(-1)) #define SOCKET_ERROR (-1) void esp8266_send(JsVar *msg) { JsvStringIterator it; jsvStringIteratorNew(&it, msg, 0); while (jsvStringIteratorHasChar(&it)) { char ch = jsvStringIteratorGetChar(&it); jshTransmit(consoleDevice, (unsigned char)ch); jsvStringIteratorNext(&it); } jsvStringIteratorFree(&it); } JsVar *esp8266_sendAndWait(JsVar *msg, int milliseconds) { esp8266_send(msg); return 0; } typedef enum { ESP8266_IDLE, ESP8266_RESET_WAIT, } ESP8266State; // name resolution #include "wiznet/DNS/dns.h" extern uint8_t Server_IP_Addr[4]; unsigned short wiznetSocketPorts[8]; unsigned char wiznetSocketAsServerClient = 0; #define WIZNET_SERVER_CLIENT 256 // sockets are only 0-255 so this is masked out uint8_t net_esp8266_getFreeSocket() { unsigned int i; for (i=0;i<8;i++) if (getSn_SR(i) == SOCK_CLOSED) // it's free! return (uint8_t)i; jsError("No free sockets found\n"); // out of range will probably just make it error out return 8; } /// Get an IP address from a name. Sets out_ip_addr to 0 on failure void net_esp8266_gethostbyname(JsNetwork *net, char * hostName, unsigned long* out_ip_addr) { NOT_USED(net); if (dns_query(0, net_esp8266_getFreeSocket(), (uint8_t*)hostName) == 1) { *out_ip_addr = *(unsigned long*)&Server_IP_Addr[0]; } } /// Called on idle. Do any checks required for this device void net_esp8266_idle(JsNetwork *net) { NOT_USED(net); } /// Call just before returning to idle loop. This checks for errors and tries to recover. Returns true if no errors. bool net_esp8266_checkError(JsNetwork *net) { NOT_USED(net); bool hadErrors = false; return hadErrors; } /// if host=0, creates a server otherwise creates a client (and automatically connects). Returns >=0 on success int net_esp8266_createsocket(JsNetwork *net, unsigned long host, unsigned short port) { NOT_USED(net); int sckt = -1; if (host!=0) { // ------------------------------------------------- host (=client) //mgg1010 - added random source port - seems to solve problem of repeated GET failing sckt = socket(net_esp8266_getFreeSocket(), Sn_MR_TCP, (uint16_t)((rand() & 32767) + 2000), 0); // we set nonblocking later if (sckt<0) return sckt; // error int res = connect((uint8_t)sckt,(uint8_t*)&host, port); // now we set nonblocking - so that connect waited for the connection uint8_t ctl = SOCK_IO_NONBLOCK; ctlsocket((uint8_t)sckt, CS_SET_IOMODE, &ctl); if (res == SOCKET_ERROR) { jsError("Connect failed (err %d)\n", res ); } } else { // ------------------------------------------------- no host (=server) sckt = socket(net_esp8266_getFreeSocket(), Sn_MR_TCP, port, SF_IO_NONBLOCK); listen((uint8_t)sckt); } wiznetSocketPorts[sckt&7] = port; //jsiConsolePrintf("Created socket %d\n", sckt); return sckt; } /// destroys the given socket void net_esp8266_closesocket(JsNetwork *net, int sckt) { NOT_USED(net); // try and close gracefully disconnect((uint8_t)sckt); JsSysTime timeout = jshGetSystemTime()+jshGetTimeFromMilliseconds(1000); uint8_t status; while ((status=getSn_SR((uint8_t)sckt)) != SOCK_CLOSED && jshGetSystemTime()idle = net_esp8266_idle; net->checkError = net_esp8266_checkError; net->createsocket = net_esp8266_createsocket; net->closesocket = net_esp8266_closesocket; net->accept = net_esp8266_accept; net->gethostbyname = net_esp8266_gethostbyname; net->recv = net_esp8266_recv; net->send = net_esp8266_send; }