commit 7f3e8a6c5bc7fc50a51071a3f1540017a25d1ab5 Author: Mimmo Date: Mon Feb 28 13:49:08 2011 +0100 WiFi API first draft diff --git a/WiFi/Client.cpp b/WiFi/Client.cpp new file mode 100755 index 000000000..36f54cde7 --- /dev/null +++ b/WiFi/Client.cpp @@ -0,0 +1,164 @@ +extern "C" { + #include "wl_types.h" + #include "socket.h" + #include "string.h" +} + +#include "WProgram.h" + +#include "WiFi.h" +#include "Client.h" +#include "Server.h" +#include "server_drv.h" + +uint16_t Client::_srcport = 0; + +Client::Client(uint8_t sock) { + _sock = sock; +} + +Client::Client(uint8_t *ip, uint16_t port) { + _ip = ip; + _port = port; + _sock = 255; +} + +uint8_t Client::getFirstSock() +{ + for (int i = 0; i < MAX_SOCK_NUM; i++) { + if (WiFiClass::_state[i] < 0) + { + return i; + } + } + return SOCK_NOT_AVAIL; +} + +uint8_t Client::connect() { + _sock = getFirstSock(); + +// _srcport++; +// if (_srcport + 1024 == 0) _srcport = 0; + _socket = socket(TCP_SOCKET); + if (_socket<0) + { + return 0; + }else{ + WiFiClass::_state[_sock] = _socket; + } + + if (!::connect(_socket, _ip, _port)) { + return 0; + } + return 1; +} + +void Client::write(uint8_t b) { + if (_sock != 255) + { + while (!ServerDrv::isDataSent(_sock)); + ServerDrv::sendData(_sock, &b, 1); + } +} + +void Client::write(const char *str) { + if (_sock != 255) + { + while (!ServerDrv::isDataSent(_sock)); + unsigned int len = strlen(str); + ServerDrv::sendData(_sock, (const uint8_t *)str, len); + } +} + +void Client::write(const uint8_t *buf, size_t size) { + if (_sock != 255) + { + while (!ServerDrv::isDataSent(_sock)); + ServerDrv::sendData(_sock, buf, size); + } + +} + +int Client::available() { + if (_sock != 255) + { + return ServerDrv::availData(_sock); + } + + return 0; +} + +int Client::read() { + uint8_t b; + if (!available()) + return -1; + ServerDrv::getData(_sock, &b); + return b; +} + + +int Client::readBuf(uint8_t* buf, uint16_t* len) { + if (!ServerDrv::getDataBuf(_sock, buf, len)) + return -1; + return 0; +} + +void Client::flush() { + while (available()) + read(); +} + +void Client::stop() { + if (_sock == 255) + return; + + // attempt to close the connection gracefully (send a FIN to other side) + disconnect(WiFiClass::_state[_sock]); + unsigned long start = millis(); + + // wait a second for the connection to close + while (status() != CLOSED && millis() - start < 1000) + delay(1); + + // if it hasn't closed, close it forcefully + if (status() != CLOSED) + close(_sock); + + WiFiClass::_server_port[_sock] = 0; + _sock = 255; +} + +uint8_t Client::connected() { + if (_sock == 255) { + return 0; + } else { + uint8_t s = status(); + return !(s == LISTEN || s == CLOSED || s == FIN_WAIT_1 || s == FIN_WAIT_2 || + (s == CLOSE_WAIT && !available())); + } +} + +uint8_t Client::status() { + if (_sock == 255) { + return CLOSED; + } else { + return ServerDrv::getState(_sock); + } +} + +// the next three functions are a hack so we can compare the client returned +// by Server::available() to null, or use it as the condition in an +// if-statement. this lets us stay compatible with the Processing network +// library. + +uint8_t Client::operator==(int p) { + return _sock == 255; +} + +uint8_t Client::operator!=(int p) { + return _sock != 255; +} + +Client::operator bool() { + return _sock != 255; +} diff --git a/WiFi/Client.h b/WiFi/Client.h new file mode 100755 index 000000000..621229155 --- /dev/null +++ b/WiFi/Client.h @@ -0,0 +1,35 @@ +#ifndef Client_h +#define Client_h + +#include "Print.h" + +class Client : public Print { +private: + static uint16_t _srcport; + uint8_t _sock; //not used + uint8_t *_ip; + uint16_t _port; + uint16_t _socket; + +public: + Client(uint8_t); + Client(uint8_t *, uint16_t); + uint8_t status(); + uint8_t connect(); + virtual void write(uint8_t); + virtual void write(const char *str); + virtual void write(const uint8_t *buf, size_t size); + int available(); + int read(); + int readBuf(uint8_t* buf, uint16_t* len); + void flush(); + void stop(); + uint8_t connected(); + uint8_t operator==(int); + uint8_t operator!=(int); + operator bool(); + uint8_t getFirstSock(); + friend class Server; +}; + +#endif diff --git a/WiFi/Server.cpp b/WiFi/Server.cpp new file mode 100755 index 000000000..e9b58137e --- /dev/null +++ b/WiFi/Server.cpp @@ -0,0 +1,78 @@ +#include +#include "HardwareSerial.h" +#include "wifi_spi.h" +#include "Server.h" +#include "Client.h" +#include "WiFi.h" +#include "server_drv.h" +#include "wiring.h" + +Server::Server(uint16_t port) +{ + _port = port; +} + +void Server::begin() +{ + uint8_t _sock = WiFiClass::getSocket(); + if (_sock != NO_SOCKET_AVAIL) + { + ServerDrv::StartServer(_port, _sock); + WiFiClass::_server_port[_sock] = _port; + } +} + +Client Server::available(byte* status) +{ + //accept(); + + for (int sock = 0; sock < MAX_SOCK_NUM; sock++) + { + if (WiFiClass::_server_port[sock] != 0) + { + Client client(sock); + *status = client.status(); + + if (WiFiClass::_server_port[sock] == _port && + *status == ESTABLISHED) + { + return client; //TODO + }else{ + delayMicroseconds(100); + } + + } + } + + return Client(255); +} + +void Server::write(uint8_t b) +{ + write(&b, 1); +} + +void Server::write(const char *str) +{ + write((const uint8_t *)str, strlen(str)); +} + +void Server::write(const uint8_t *buffer, size_t size) +{ + for (int sock = 0; sock < MAX_SOCK_NUM; sock++) + { + if (WiFiClass::_server_port[sock] != 0) + { + Client client(sock); + + if (WiFiClass::_server_port[sock] == _port && + client.status() == ESTABLISHED) + { + client.write(buffer, size); + }else{ + delay(20); + } + + } + } +} diff --git a/WiFi/Server.h b/WiFi/Server.h new file mode 100755 index 000000000..fdab7945b --- /dev/null +++ b/WiFi/Server.h @@ -0,0 +1,25 @@ +#ifndef Server_h +#define Server_h + +extern "C" { + #include "utility/wl_types.h" +} + +#include "Print.h" + +class Client; + +class Server : public Print { +private: + uint16_t _port; + void* pcb; +public: + Server(uint16_t); + Client available(uint8_t*); + void begin(); + virtual void write(uint8_t); + virtual void write(const char *str); + virtual void write(const uint8_t *buf, size_t size); +}; + +#endif diff --git a/WiFi/WiFi.cpp b/WiFi/WiFi.cpp new file mode 100755 index 000000000..e68a98d42 --- /dev/null +++ b/WiFi/WiFi.cpp @@ -0,0 +1,184 @@ +#include "WProgram.h" +#include "WiFi.h" +#include +#include "HardwareSerial.h" +#include "wifi_drv.h" + + +// XXX: don't make assumptions about the value of MAX_SOCK_NUM. +int16_t WiFiClass::_state[MAX_SOCK_NUM] = { 0, 0, 0, 0 }; +uint16_t WiFiClass::_server_port[MAX_SOCK_NUM] = { 0, 0, 0, 0 }; + +char WiFiClass::ssid[WL_SSID_MAX_LENGTH] = { 0 }; +uint8_t WiFiClass::ssid_len; +char WiFiClass::key[13] = { 0 }; +uint8_t WiFiClass::key_len; +char WiFiClass::passph[63] = { 0 }; +uint8_t WiFiClass::passph_len; +wl_status_t WiFiClass::status; + +void readEEdata(int addr, uint8_t* data, uint8_t len) +{ + for (int i = 0; i < len; ++i) + { + data[i]= EEPROM.read(addr); + } +} + +WiFiClass::WiFiClass() +{ +} + +void WiFiClass::init() +{ + Serial.begin(9600); + Serial.println("WiFi initializing..."); + WiFiDrv::wifi_drv_init(); +} + + +uint8_t WiFiClass::getSocket() +{ + for (uint8_t i = 0; i < MAX_SOCK_NUM; ++i) + { + if (WiFiClass::_server_port[i] == 0) + { + return i; + } + } + return NO_SOCKET_AVAIL; +} + +void WiFiClass::begin() +{ + init(); + Serial.println("WiFi Starting..."); + ssid_len = EEPROM.read(EE_WIFI_SSID_LEN); + if ((ssid_len == 0)||(ssid_len > WL_SSID_MAX_LENGTH)) + { + Serial.println("No SSID in EEPROM"); + + status = WL_NO_SSID_AVAIL; + return; + } + readEEdata(EE_WIFI_SSID_DATA, (uint8_t*)&ssid[0], ssid_len); + + Serial.print("SSID: "); + Serial.print(ssid_len, 10); + Serial.print(" - "); + Serial.print(ssid[0]); + Serial.println(""); + key_len = EEPROM.read(EE_WIFI_KEY_LEN); + if (key_len == 0) + { + Serial.println("No PASSPHRASE in EEPROM"); + + passph_len = EEPROM.read(EE_WIFI_PASSPH_LEN); + if (passph_len == 0) + { + begin(ssid, ssid_len); + }else{ + readEEdata(EE_WIFI_PASSPH_DATA, (uint8_t*)&passph[0], passph_len); + beginp(ssid,ssid_len,&passph[0],passph_len); + } + }else{ + Serial.println("No KEY in EEPROM"); + + readEEdata(EE_WIFI_KEY_DATA, (uint8_t*)&key[0], key_len); + begink(ssid,ssid_len, 0, &key[0],key_len); + } +} + +void WiFiClass::begin(char* ssid, uint8_t ssid_len) +{ + wl_error_code_t result = (wl_error_code_t)WiFiDrv::wifi_set_net(ssid, ssid_len); + if (result == WL_SUCCESS) + { + status = WL_CONNECTED; + Serial.println("WiFi Connected!"); + }else{ + status = WL_CONNECT_FAILED; + Serial.println("WiFi Connection failed!"); + } +} + +void WiFiClass::begink(char* ssid, uint8_t ssid_len, uint8_t key_idx, const void *key, const uint8_t key_len) +{ + // set encryption key + wl_error_code_t result = (wl_error_code_t)WiFiDrv::wifi_set_key(ssid, ssid_len, key_idx, key, key_len); + if (result == WL_SUCCESS) + { + //begin(ssid, ssid_len); + }else{ + // Error setting passphrase + } + +} + +void WiFiClass::beginp(char* ssid, uint8_t ssid_len, const char *passphrase, const uint8_t len) +{ + // set passphrase + wl_error_code_t result = (wl_error_code_t)WiFiDrv::wifi_set_passpharse(ssid, ssid_len, passphrase, len); + if (result == WL_SUCCESS) + { + //begin(ssid, ssid_len); + }else{ + // Error setting passphrase + } +} + +wl_status_t WiFiClass::get_status() +{ + return status; +} + +uint8_t WiFiClass::get_result(uint8_t dummy) +{ + uint8_t result = WiFiDrv::wifi_get_result(dummy); + return result; +} + + +void WiFiClass::getIpAddr(uint8_t *ip, uint8_t *mask, uint8_t *gwip) +{ + WiFiDrv::getIpAddr(ip,mask,gwip); +} + + +uint8_t WiFiClass::getMacAddr(uint8_t* mac) +{ + return WiFiDrv::wl_get_mac_addr(mac); +} + +void WiFiClass::getSSIDList(char** ssid_list, uint8_t* ssidListNum) +{ + WiFiDrv::getSSIDList(ssid_list, ssidListNum); +} + +void WiFiClass::getCurrSSID(char* ssid) +{ + WiFiDrv::getCurrSSID(ssid); +} + +void WiFiClass::getCurrBSSID(uint8_t* bssid) +{ + WiFiDrv::getCurrBSSID(bssid); +} + +void WiFiClass::getCurrRSSI(int32_t* rssi) +{ + WiFiDrv::getCurrRSSI(rssi); +} + +void WiFiClass::getCurrEncType(uint8_t* enc_type) +{ + WiFiDrv::getCurrEncType(enc_type); +} + +uint8_t WiFiClass::disconnect() +{ + return WiFiDrv::disconnect(); +} + + +WiFiClass WiFi; diff --git a/WiFi/WiFi.h b/WiFi/WiFi.h new file mode 100755 index 000000000..d4edb3ec4 --- /dev/null +++ b/WiFi/WiFi.h @@ -0,0 +1,100 @@ +#ifndef WiFi_h +#define WiFi_h + +#include + +extern "C" { + #include "utility/wl_types.h" + #include "utility/wifi_spi.h" + #include "utility/debug.h" // only for test, not released +} + +#include "Client.h" +#include "Server.h" + +// location in EEPROM to store key information +#define EE_WIFI_DATA_ADDR 0x10 +#define EE_WIFI_SSID_LEN EE_WIFI_DATA_ADDR +#define EE_WIFI_KEY_LEN EE_WIFI_DATA_ADDR + 1 +#define EE_WIFI_PASSPH_LEN EE_WIFI_DATA_ADDR + 2 +#define EE_WIFI_SSID_DATA EE_WIFI_DATA_ADDR + 3 +#define EE_WIFI_KEY_DATA EE_WIFI_DATA_ADDR + 4 +#define EE_WIFI_PASSPH_DATA EE_WIFI_DATA_ADDR + 4 +// Note: Or KEY or PASSPH can be defined. +// The selection is made by the len not equal to zero + +class WiFiClass +{ +private: + // this data are stored in EEPROM and loaded at begin + // The next connect overwrite these values + static char ssid[WL_SSID_MAX_LENGTH]; + static uint8_t ssid_len; + static char key[13]; + static uint8_t key_len; + static char passph[63]; + static uint8_t passph_len; + static wl_status_t status; + + void init(); +public: + //static wl_state_t _wl_state[MAX_SOCK_NUM]; + static int16_t _state[MAX_SOCK_NUM]; + static uint16_t _server_port[MAX_SOCK_NUM]; + WiFiClass(); + + // Start Wifi connection with data stored in EEPROM + void begin(); + + // Start Wifi connection without WEP or WPA + void begin(char* ssid, uint8_t ssid_len); + + // Start Wifi connection with WEP + void begink(char* ssid, uint8_t ssid_len, uint8_t key_idx, const void *key, const uint8_t key_len); + + // Start Wifi connection with WPA + void beginp(char* ssid, uint8_t ssid_len, const char *passphrase, const uint8_t len); + + //getSock get the first socket available + static uint8_t getSocket(); + + // verify the completion of the scan command + wl_status_t get_status(); + + // get the result of the last operation + uint8_t get_result(uint8_t dummy = 0); + + // Disconnect from the network + uint8_t disconnect(void); + + //Get the interface MAC address. + uint8_t getMacAddr(uint8_t* mac); + + //Get the DHCP infortion related to IP, netmas, gateway + void getIpAddr(uint8_t *ip, uint8_t *mask, uint8_t *gwip); + + // Get the list of currently known networks. + wl_error_code_t wl_get_network_list(struct wl_network_t** network_list, uint8_t* network_cnt); + + // Return a list of all SSID available + void getSSIDList(char** ssid_list, uint8_t* ssidListNum); + + // Return the current SSID associated with the network + void getCurrSSID(char* ssid); + + // Return the current BSSID associated with the network + void getCurrBSSID(uint8_t* bssid); + + // Return the current RSSI associated with the network + void getCurrRSSI(int32_t* rssi); + + // Return the current Encryption Type associated with the network + void getCurrEncType(uint8_t* enc_type); + + friend class Client; + friend class Server; +}; + +extern WiFiClass WiFi; + +#endif diff --git a/WiFi/examples/wifi_example/wifi_example.pde b/WiFi/examples/wifi_example/wifi_example.pde new file mode 100755 index 000000000..a96c5fc32 --- /dev/null +++ b/WiFi/examples/wifi_example/wifi_example.pde @@ -0,0 +1,29 @@ +/* + WiFi example + + A simple connection with WiFi AP with Wireless Security + information loaded in EEPROM + + created 13 July 2010 + by Domenico La Fauci + */ + +#include +#include + +void setup() +{ + Serial.begin(9600); + WiFi.begin(); + if (WiFi.get_status() == WL_NO_SSID_AVAIL) + { + // SSID not present in EEPROM + char ssid[] = "Cariddi"; + WiFi.begin(ssid, strlen(ssid)); + } +} + +void loop() +{ +} + diff --git a/WiFi/examples/wifi_example2/wifi_example2.pde b/WiFi/examples/wifi_example2/wifi_example2.pde new file mode 100755 index 000000000..d16908300 --- /dev/null +++ b/WiFi/examples/wifi_example2/wifi_example2.pde @@ -0,0 +1,107 @@ +/* + WiFi example + + A simple connection with WiFi AP with Wireless Security + information loaded in EEPROM, if not available + try to access with WPA or WEP security keys + + created 13 July 2010 + by Domenico La Fauci + */ + +#include +#include +#include + +// network configuration. gateway and subnet are optional. +byte mac[6] = { 0 }; +byte ip[4] = { 0 }; +byte gateway[4] = { 0 }; +byte subnet[4] = { 0 }; + + +void setup() +{ + Serial.begin(9600); + Serial.println("Setup WiFi..."); + WiFi.begin(); + if (WiFi.get_status() == WL_NO_SSID_AVAIL) + { + //uint8_t result = WiFi.get_result(); + //Serial.println(result,16); + + // SSID not present in EEPROM + char ssid[] = "Cariddi"; + Serial.println(ssid); + delay(2000); + + // Using WPA + WiFi.begin(ssid, strlen(ssid)); + delay(10000); + if (WiFi.get_result() == WL_CONNECT_FAILED) + { + Serial.println("Trying with Passphrase..."); + uint8_t key_idx = 0; + const char *pass = "12345678"; + uint8_t pass_len = strlen(pass); + WiFi.beginp(ssid, strlen(ssid), pass, pass_len); + } + // wait to trying connection... + delay(5000); + + // using WEP + if (WiFi.get_result() == WL_CONNECT_FAILED) + { + Serial.println("Trying with Key..."); + uint8_t key_idx = 0; + const char *key = "12345678"; + uint8_t key_len = strlen(key); + WiFi.begink(ssid, strlen(ssid),key_idx, key, key_len); + } + // wait to trying connection... + delay(5000); + + { + WiFi.getIpAddr(ip,subnet,gateway); + Serial.print("IP: "); + Serial.print(ip[3],10);Serial.print("."); + Serial.print(ip[2],10);Serial.print("."); + Serial.print(ip[1],10);Serial.print("."); + Serial.println(ip[0],10); + + Serial.print("NETMASK: "); + Serial.print(subnet[3],10);Serial.print("."); + Serial.print(subnet[2],10);Serial.print("."); + Serial.print(subnet[1],10);Serial.print("."); + Serial.println(subnet[0],10); + + Serial.print("GATEWAY: "); + Serial.print(gateway[3],10);Serial.print("."); + Serial.print(gateway[2],10);Serial.print("."); + Serial.print(gateway[1],10);Serial.print("."); + Serial.println(gateway[0],10); + + WiFi.getMacAddr(mac); + Serial.print("MAC: "); + Serial.print(mac[5],16);Serial.print(":"); + Serial.print(mac[4],16);Serial.print(":"); + Serial.print(mac[3],16);Serial.print(":"); + Serial.print(mac[2],16);Serial.print(":"); + Serial.print(mac[1],16);Serial.print(":"); + Serial.println(mac[0],16); + + } + } +} + +void loop() +{ + static uint8_t count = 0; + while (WiFi.get_status() != WL_CONNECTED) + { + uint8_t result = WiFi.get_result(count++); + Serial.println(result); + delay(3000); + } +} + diff --git a/WiFi/keywords.txt b/WiFi/keywords.txt new file mode 100755 index 000000000..ce613bdbb --- /dev/null +++ b/WiFi/keywords.txt @@ -0,0 +1,45 @@ +####################################### +# Syntax Coloring Map For WiFi +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +WiFi KEYWORD1 +Client KEYWORD1 +Server KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +status KEYWORD2 +connect KEYWORD2 +write KEYWORD2 +available KEYWORD2 +read KEYWORD2 +flush KEYWORD2 +stop KEYWORD2 +connected KEYWORD2 +begin KEYWORD2 +begink KEYWORD2 +beginp KEYWORD2 +disconnect KEYWORD2 +getMacAddr KEYWORD2 +getIpAddr KEYWORD2 +getSSIDList KEYWORD2 +getCurrSSID KEYWORD2 +getCurrBSSID KEYWORD2 +getCurrRSSI KEYWORD2 +getCurrEncType KEYWORD2 +wl_get_network_list KEYWORD2 +get_result KEYWORD2 +get_status KEYWORD2 +getSocket KEYWORD2 + + +####################################### +# Constants (LITERAL1) +####################################### +