This is Wi-Fi interface of WizFi310 for mbed os 5
Dependents: mbed-os-example-wifi
Revision 0:d0e3f515f99d, committed 2017-12-18
- Comitter:
- kaizen
- Date:
- Mon Dec 18 23:25:46 2017 +0000
- Child:
- 1:8e468bb83e1e
- Commit message:
- First commit WizFi310Interface_Draft for mbed OS5
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TESTS/udp_echo/main.cpp Mon Dec 18 23:25:46 2017 +0000 @@ -0,0 +1,156 @@ +/* WiFi Example + * Copyright (c) 2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mbed.h" +#include "TCPSocket.h" + +#define WIFI_ESP8266 1 +#define WIFI_IDW0XX1 2 +#define WIFI_WIZFI310 3 + +#if TARGET_UBLOX_EVK_ODIN_W2 +#include "OdinWiFiInterface.h" +OdinWiFiInterface wifi; + +#elif TARGET_REALTEK_RTL8195AM +#include "RTWInterface.h" +RTWInterface wifi; + +#else // External WiFi modules + +#if MBED_CONF_APP_WIFI_SHIELD == WIFI_ESP8266 +#include "ESP8266Interface.h" +ESP8266Interface wifi(MBED_CONF_APP_WIFI_TX, MBED_CONF_APP_WIFI_RX); +#elif MBED_CONF_APP_WIFI_SHIELD == WIFI_IDW0XX1 +#include "SpwfSAInterface.h" +SpwfSAInterface wifi(MBED_CONF_APP_WIFI_TX, MBED_CONF_APP_WIFI_RX); +#elif MBED_CONF_APP_WIFI_SHIELD == WIFI_WIZFI310 +#include "WizFi310Interface.h" +WizFi310Interface wifi(MBED_CONF_APP_WIFI_TX, MBED_CONF_APP_WIFI_RX); +#endif // MBED_CONF_APP_WIFI_SHIELD == WIFI_WIZFI310 + +#endif + +#ifndef MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE +#define MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE 5 +#endif + +namespace { + char tx_buffer[MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE] = {0}; + char rx_buffer[MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE] = {0}; + const char ASCII_MAX = '~' - ' '; + const int ECHO_LOOPS = 16; + char uuid[48] = {0}; +} + +void prep_buffer(char *uuid, char *tx_buffer, size_t tx_size) { + size_t i = 0; + + memcpy(tx_buffer, uuid, strlen(uuid)); + i += strlen(uuid); + + tx_buffer[i++] = ' '; + + for (; i<tx_size; ++i) { + tx_buffer[i] = (rand() % 10) + '0'; + } +} + +void test_udp_echo(NetworkInterface *net) +{ + printf("UDP client IP Address is %s\n", net->get_ip_address()); + + printf("target_ip %s\r\n", net->get_ip_address()); + char recv_key[] = "host_port"; + char ipbuf[60] = {0}; + char portbuf[16] = {0}; + unsigned int port = 5000; + + UDPSocket sock; + sock.open(net); + sock.set_timeout(500); + + //printf("MBED: UDP Server IP address received: %s:%d \n", ipbuf, port); + nsapi_addr_t addr = {NSAPI_IPv4, 192,168,1,46}; + SocketAddress udp_addr(addr, port); + + int success = 0; + for (int i=0; success < ECHO_LOOPS; i++) + { + prep_buffer(uuid, tx_buffer, sizeof(tx_buffer)); + const int ret = sock.sendto(udp_addr, tx_buffer, sizeof(tx_buffer)); + if (ret >= 0) { + printf("[%02d] sent %d bytes - %.*s \n", i, ret, ret, tx_buffer); + } else { + printf("[%02d] Network error %d\n", i, ret); + continue; + } + + SocketAddress temp_addr; + const int n = sock.recvfrom(&temp_addr, rx_buffer, sizeof(rx_buffer)); + if (n >= 0) { + printf("[%02d] recv %d bytes - %.*s \n", i, n, n, rx_buffer); + } else { + printf("[%02d] Network error %d\n", i, n); + continue; + } + + if ((temp_addr == udp_addr && + n == sizeof(tx_buffer) && + memcmp(rx_buffer, tx_buffer, sizeof(rx_buffer)) == 0)) { + success += 1; + + printf("[%02d] success #%d\n", i, success); + continue; + } + + // failed, clean out any remaining bad packets + sock.set_timeout(0); + while (true) { + nsapi_size_or_error_t err = sock.recvfrom(NULL, NULL, 0); + if (err == NSAPI_ERROR_WOULD_BLOCK) { + break; + } + } + sock.set_timeout(500); + } + sock.close(); + net->disconnect(); +} + +int main() +{ + int count = 0; + + printf("WiFi example\n\n"); + printf("\nConnecting to %s...\n", MBED_CONF_APP_WIFI_SSID); + int ret = wifi.connect(MBED_CONF_APP_WIFI_SSID, MBED_CONF_APP_WIFI_PASSWORD, NSAPI_SECURITY_WPA_WPA2); + if (ret != 0) { + printf("\nConnection error\n"); + return -1; + } + + printf("Success\n\n"); + printf("MAC: %s\n", wifi.get_mac_address()); + printf("IP: %s\n", wifi.get_ip_address()); + printf("Netmask: %s\n", wifi.get_netmask()); + printf("Gateway: %s\n", wifi.get_gateway()); + printf("RSSI: %d\n\n", wifi.get_rssi()); + + test_udp_echo(&wifi); + wifi.disconnect(); + printf("\nDone\n"); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WizFi310/WizFi310.cpp Mon Dec 18 23:25:46 2017 +0000 @@ -0,0 +1,465 @@ +/* WizFi310 Example + * Copyright (c) 2015 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "WizFi310.h" +#define WIZFI310_DEFAULT_BAUD_RATE 115200 + +WizFi310::WizFi310(PinName tx, PinName rx, bool debug) + : _serial(tx, rx, WIZFI310_DEFAULT_BAUD_RATE), + _parser(&_serial), + _packets(0), + _packets_end(&_packets) +{ + _serial.set_baud( WIZFI310_DEFAULT_BAUD_RATE ); + _parser.debug_on(debug); + _parser.set_delimiter("\r"); + + //_parser.recv("WizFi310 Version %s (WIZnet Co.Ltd)", _firmware_version); + for(int i=0; i<10; i++) + { + if( _parser.send("AT") && _parser.recv("[OK]") ) + { + _parser.send("AT+MRESET"); + _parser.recv("[OK]"); + break; + } + } + + _parser.recv("WizFi310 Version %s (WIZnet Co.Ltd)", _firmware_version); +} + +const char* WizFi310::get_firmware_version() +{ + if( strlen(_firmware_version) != 0 ) + { + return _firmware_version; + } + + _parser.send("AT+MINFO"); + if( _parser.recv("%s/WizFi310 Rev", _firmware_version) ) + { + return _firmware_version; + } + + return 0; +} + +bool WizFi310::startup(int mode) +{ + if( mode != 0 && mode != 1 ) + { + return false; + } + _op_mode = mode; + + _parser.oob("{", callback(this, &WizFi310::_packet_handler)); + return true; +} + +bool WizFi310::reset(void) +{ + for (int i=0; i<2; i++) + { + if(_parser.send("AT+MRESET") + && _parser.recv("[OK]")) + { + return true; + } + } + + return false; +} + +bool WizFi310::dhcp(bool enabled) +{ + _dhcp = enabled; + return _dhcp; +} + +bool WizFi310::connect(const char *ap, const char *passPhrase, const char *sec) +{ + if ( !(_parser.send("AT+WSET=0,%s", ap) && _parser.recv("[OK]")) ) + { + return false; + } + + if ( !(_parser.send("AT+WSEC=0,%s,%s", sec, passPhrase) && _parser.recv("[OK]")) ) + { + return false; + } + + if (_dhcp) + { + if ( !(_parser.send("AT+WNET=1") && _parser.recv("[OK]")) ) + { + return false; + } + } + else + { + if ( !(_parser.send("AT+WNET=0,%s,%s,%s",_ip_buffer,_netmask_buffer,_gateway_buffer) + && _parser.recv("[OK]")) ) + { + return false; + } + } + + if ( !(_parser.send("AT+WJOIN") && _parser.recv("[Link-Up Event]") + && _parser.recv(" IP Addr : %[^\n]\r\n",_ip_buffer) + && _parser.recv(" Gateway : %[^\n]\r\n",_gateway_buffer) + && _parser.recv("[OK]")) ) + { + return false; + } + + return true; +} + +bool WizFi310::disconnect(void) +{ + return _parser.send("AT+WLEAVE") && _parser.recv("[OK]"); +} + +const char *WizFi310::getIPAddress(void) +{ + if (!(_parser.send("AT+WSTATUS") && _parser.recv("IF/SSID/IP-Addr/Gateway/MAC/TxPower(dBm)/RSSI(-dBm)") + && _parser.recv("%*[^/]/%*[^/]/%15[^/]/",_ip_buffer) + && _parser.recv("[OK]")) ) + { + return 0; + } + + return _ip_buffer; +} + +const char *WizFi310::getMACAddress(void) +{ + if (!(_parser.send("AT+MMAC=?") + && _parser.recv("%[^\n]\r\n",_mac_buffer) + && _parser.recv("[OK]"))) { + return 0; + } + + return _mac_buffer; +} + +const char *WizFi310::getGateway() +{ + return _gateway_buffer; +} + +const char *WizFi310::getNetmask() +{ + return _netmask_buffer; +} + +int8_t WizFi310::getRSSI() +{ + char rssi[3]; + + if (!(_parser.send("AT+WSTATUS") && _parser.recv("IF/SSID/IP-Addr/Gateway/MAC/TxPower(dBm)/RSSI(-dBm)") + //&& _parser.recv("%*[^/]/%*[^/]/%*[^/]/%*[^/]/%*[^/]/%*[^/]/%[^\n]\r\n",&rssi) + && _parser.recv("%*[^/]/%*[^/]/%*[^/]/%*[^/]/%*[^/]//%[^\n]\r\n",rssi) + && _parser.recv("[OK]")) ) + { + return 0; + } + + return atoi(rssi); +} + +bool WizFi310::isConnected(void) +{ + return getIPAddress() != 0; +} + +int WizFi310::scan(WiFiAccessPoint *res, unsigned limit) +{ + unsigned int cnt = 0; + nsapi_wifi_ap_t ap; + + if (!(_parser.send("AT+WSCAN") + && _parser.recv("Index/SSID/BSSID/RSSI(-dBm)/MaxDataRate(Mbps)/Security/RadioBand(GHz)/Channel"))) + { + return NSAPI_ERROR_DEVICE_ERROR; + } + + while (recv_ap(&ap)) { + if (cnt < limit) + { + res[cnt] = WiFiAccessPoint(ap); + } + cnt++; + if (limit != 0 && cnt >= limit) + { + break; + } + } + + return cnt; +} + +bool WizFi310::open(const char *type, int id, const char* addr, int port) +{ + int created_sock_id; + + //IDs only 0-7 + if(id > 7) { + return false; + } + + if( !(_parser.send("AT+SCON=O,%s,%s,%d,,0",type,addr,port) && _parser.recv("[OK]")) ) { + return false; + } + + if( !(_parser.recv("[CONNECT %d]",&created_sock_id)) ) { + return false; + } + + if( created_sock_id != id ) { + close(created_sock_id); + return false; + } + + return true; +} + +bool WizFi310::dns_lookup(const char* name, char* ip) +{ + return _parser.send("AT+FDNS=%s,10000", name) && _parser.recv("%s%*[\r]%*[\n]",ip) + && _parser.recv("[OK]"); +} + +bool WizFi310::send(int id, const void *data, uint32_t amount) +{ + char str_result[20]; + sprintf(str_result,"[%d,,,%d]",id,amount); + + for (unsigned i=0; i<2; i++) { + if( _parser.send("AT+SSEND=%d,,,%d",id, amount) + && _parser.recv(str_result) + && _parser.write((char*)data, (int)amount) >= 0 + && _parser.recv("[OK]") ){ + return true; + } + } + return false; +} + +void WizFi310::_packet_handler() +{ + int id; + char ip_addr[16]; + int port; + uint32_t amount; + + // parse out the packet + if (!_parser.recv("%d,%[^,],%d,%d}",&id, ip_addr,&port, &amount) ) { + return; + } + + struct packet *packet = (struct packet*)malloc( + sizeof(struct packet) + amount); + if (!packet) { + return; + } + + packet->id = id; + packet->len = amount; + packet->next = 0; + + if (!(_parser.read((char*)(packet + 1), amount))) { + free(packet); + return; + } + + *_packets_end = packet; + _packets_end = &packet->next; +} + +int32_t WizFi310::recv(int id, void *data, uint32_t amount) +{ + while (true) { + // check if any packets are ready for us + for (struct packet **p = &_packets; *p; p = &(*p)->next) { + if ((*p)->id == id) { + struct packet *q = *p; + + if (q->len <= amount) { + memcpy(data, q+1, q->len); + + if (_packets_end == &(*p)->next) { + _packets_end = p; + } + *p = (*p)->next; + + uint32_t len = q->len; + free(q); + return len; + } else { // return only partial packet + memcpy(data, q+1, amount); + + q->len -= amount; + memmove(q+1, (uint8_t*)(q+1) + amount, q->len); + return amount; + } + } + } + + // check for inbound packets + if (!_parser.process_oob()) { + return -1; + } + } +} + +bool WizFi310::close(int id) +{ + char sock_event_msg[15]; + sprintf(sock_event_msg,"[DISCONNECT %d]",id); + + if (_parser.send("AT+SMGMT=%d", id) && _parser.recv("[OK]") && _parser.recv(sock_event_msg) ) + { + return true; + } + + return false; +} + +void WizFi310::setTimeout(uint32_t timeout_ms) +{ + _parser.set_timeout(timeout_ms); +} + +bool WizFi310::readable() +{ + return _serial.FileHandle::readable(); +} + +bool WizFi310::writeable() +{ + return _serial.FileHandle::writable(); +} + +void WizFi310::attach(Callback<void()> func) +{ + _serial.sigio(func); +} + +bool WizFi310::recv_ap(nsapi_wifi_ap_t *ap) +{ + char scan_result[100]; + char sec[10]; + char bssid[32]; + char* idx_ptr; + char* bssid_ptr; + + _parser.recv("%s\r\n",scan_result); + if( strcmp(scan_result,"[OK]") == 0 ) + { + return false; + } + + idx_ptr = strtok((char*)scan_result, "/"); // index + + idx_ptr = strtok( NULL, "/" ); // ssid + strncpy(ap->ssid,idx_ptr,strlen(idx_ptr)); + ap->ssid[strlen(idx_ptr)] = '\0'; + + idx_ptr = strtok( NULL, "/" ); // bssid + strncpy(bssid,idx_ptr,strlen(idx_ptr)); + bssid[strlen(idx_ptr)] = '\0'; + + idx_ptr = strtok( NULL, "/" ); // RSSI + ap->rssi = atoi(idx_ptr); + + //idx_ptr = strtok( NULL, "/" ); // DataRate + + idx_ptr = strtok( NULL, "/" ); // Security + strncpy(sec,idx_ptr,strlen(idx_ptr)); + sec[strlen(idx_ptr)] = '\0'; + ap->security = str2sec(sec); + + idx_ptr = strtok( NULL, "/" ); // RadioBand + + idx_ptr = strtok( NULL, "/" ); // Channel + ap->channel = atoi(idx_ptr); + + // Set BSSID + bssid_ptr = strtok( (char*)bssid, ":"); + ap->bssid[0] = hex_str_to_int(bssid_ptr); + + for(int i=1; i<6; i++) + { + bssid_ptr = strtok( NULL, ":"); + ap->bssid[i] = hex_str_to_int(bssid_ptr); + } + + return true; +} + +nsapi_security_t WizFi310::str2sec(const char *str_sec) +{ + if( strcmp(str_sec,"Open") == 0 ) + { + return NSAPI_SECURITY_NONE; + } + else if( strcmp(str_sec,"WEP") == 0 ) + { + return NSAPI_SECURITY_WEP; + } + else if( strcmp(str_sec,"WPA") == 0 ) + { + return NSAPI_SECURITY_WPA; + } + else if( strcmp(str_sec,"WPA2") == 0 ) + { + return NSAPI_SECURITY_WPA2; + } + else if( strcmp(str_sec,"WPAWPA2") == 0 ) + { + return NSAPI_SECURITY_WPA_WPA2; + } + + return NSAPI_SECURITY_UNKNOWN; +} + +int WizFi310::hex_str_to_int(const char* hex_str) +{ + int n = 0; + uint32_t value = 0; + int shift = 7; + while (hex_str[n] != '\0' && n < 8) + { + if ( hex_str[n] > 0x21 && hex_str[n] < 0x40 ) + { + value |= (hex_str[n] & 0x0f) << (shift << 2); + } + else if ( (hex_str[n] >= 'a' && hex_str[n] <= 'f') || (hex_str[n] >= 'A' && hex_str[n] <= 'F') ) + { + value |= ((hex_str[n] & 0x0f) + 9) << (shift << 2); + } + else + { + break; + } + n++; + shift--; + } + + return (value >> ((shift + 1) << 2)); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WizFi310/WizFi310.h Mon Dec 18 23:25:46 2017 +0000 @@ -0,0 +1,528 @@ + +#ifndef WIZFI310_H_ +#define WIZFI310_H_ + +#include "ATCmdParser.h" + +/** WizFi310Interface class. + This is an interface to a WizFi310Interface radio. +*/ +class WizFi310 +{ +public: + WizFi310(PinName tx, PinName rx, bool debug=false); + + /** + * Check firmware version of WizFi310 + * + * @return character array firmware version or 0 if firmware query command gives outdated response + */ + const char* get_firmware_version(void); + + /** + * Startup the WizFi310 + * + * @param mode mode of WIFI 0-client, 1-host + * @return true only if WizFi310 was setup correctly + */ + bool startup(int mode); + + /** + * Reset WizFi310 + * + * @return true only if WizFi310 resets successfully + */ + bool reset(void); + + /** + * Enable/Disable DHCP + * + * @param enabled DHCP enabled when true + * @return true only if WizFi310 enables/disables DHCP successfully + */ + bool dhcp(bool enabled); + + /** + * Connect WizFi310 to AP + * + * @param ap the name of the AP + * @param passPhrase the password of AP + * @param security type of AP + * @return true only if WizFi310 is connected successfully + */ + bool connect(const char *ap, const char *passPhrase, const char *sec); + + /** + * Disconnect WizFi310 from AP + * + * @return true only if WizFi310 is disconnected successfully + */ + bool disconnect(void); + + /** + * Get the IP address of WizFi310 + * + * @return null-teriminated IP address or null if no IP address is assigned + */ + const char *getIPAddress(void); + + /** + * Get the MAC address of WizFi310 + * + * @return null-terminated MAC address or null if no MAC address is assigned + */ + const char *getMACAddress(void); + + /** Get the local gateway + * + * @return Null-terminated representation of the local gateway + * or null if no network mask has been recieved + */ + const char *getGateway(); + + /** Get the local network mask + * + * @return Null-terminated representation of the local network mask + * or null if no network mask has been recieved + */ + const char *getNetmask(); + + /* Return RSSI for active connection + * + * @return Measured RSSI + */ + int8_t getRSSI(); + + /** + * Check if WizFi310 is conenected + * + * @return true only if the chip has an IP address + */ + bool isConnected(void); + + /** Scan for available networks + * + * @param ap Pointer to allocated array to store discovered AP + * @param limit Size of allocated @a res array, or 0 to only count available AP + * @return Number of entries in @a res, or if @a count was 0 number of available networks, negative on error + * see @a nsapi_error + */ + int scan(WiFiAccessPoint *res, unsigned limit); + + /**Perform a dns query + * + * @param name Hostname to resolve + * @param ip Buffer to store IP address + * @return 0 true on success, false on failure + */ + bool dns_lookup(const char *name, char *ip); + + /** + * Open a socketed connection + * + * @param type the type of socket to open "UDP" or "TCP" + * @param id id to give the new socket, valid 0-4 + * @param port port to open connection with + * @param addr the IP address of the destination + * @return true only if socket opened successfully + */ + bool open(const char *type, int id, const char* addr, int port); + + /** + * Sends data to an open socket + * + * @param id id of socket to send to + * @param data data to be sent + * @param amount amount of data to be sent - max 1024 + * @return true only if data sent successfully + */ + bool send(int id, const void *data, uint32_t amount); + + /** + * Receives data from an open socket + * + * @param id id to receive from + * @param data placeholder for returned information + * @param amount number of bytes to be received + * @return the number of bytes received + */ + int32_t recv(int id, void *data, uint32_t amount); + + /** + * Closes a socket + * + * @param id id of socket to close, valid only 0-4 + * @return true only if socket is closed successfully + */ + bool close(int id); + + /** + * Allows timeout to be changed between commands + * + * @param timeout_ms timeout of the connection + */ + void setTimeout(uint32_t timeout_ms); + + /** + * Checks if data is available + */ + bool readable(); + + /** + * Checks if data can be written + */ + bool writeable(); + + /** + * Attach a function to call whenever network state has changed + * + * @param func A pointer to a void function, or 0 to set as none + */ + void attach(Callback<void()> func); + + /** + * Attach a function to call whenever network state has changed + * + * @param obj pointer to the object to call the member function on + * @param method pointer to the member function to call + */ + template <typename T, typename M> + void attach(T *obj, M method) { + attach(Callback<void()>(obj, method)); + } + +private: + UARTSerial _serial; + ATCmdParser _parser; + + struct packet { + struct packet *next; + int id; + uint32_t len; + // data follows + } *_packets, **_packets_end; + void _packet_handler(); + bool recv_ap(nsapi_wifi_ap_t *ap); + nsapi_security_t str2sec(const char *str_sec); + int hex_str_to_int(const char* hex_str); + + char _ip_buffer[16]; + char _gateway_buffer[16]; + char _netmask_buffer[16]; + char _mac_buffer[18]; + char _firmware_version[8]; + + int _op_mode; // 0 : Station Mode, 1 : AP Mode + bool _dhcp; +}; + + + +//#include "WizFi310_conf.h" +// +//#include "mbed.h" +//#include "RawSerial.h" +//#include "Serial.h" +//#include "CBuffer.h" +//#include <ctype.h> +//#include <stdlib.h> +//#include <string> +//#include "WiFiInterface.h" +// +//using namespace std; +// +//#define BUF_SIZE 1600 +// +////Debug is disabled by default +//#if 1 +//#define WIZ_DBG(x, ...) std::printf("[WizFi310: DBG]" x "\r\n", ##__VA_ARGS__); +//#define WIZ_WARN(x, ...) std::printf("[WizFi310: WARN]" x "\r\n", ##__VA_ARGS__); +//#define WIZ_ERR(x, ...) std::printf("[WizFi310: ERR]" x "\r\n", ##__VA_ARGS__); +//#define WIZ_INFO(x, ...) std::printf("[WizFi310: INFO]" x "\r\n", ##__VA_ARGS__); +//#else +//#define WIZ_DBG(x, ...) +//#define WIZ_WARN(x, ...) +//#define WIZ_ERR(x, ...) +//#define WIZ_INFO(x, ...) +//#endif +// +// +//class WizFi310 +//{ +//public: +// +// enum AntennaMode{ +// PCB = 0, +// UFL = 1, +// AUTO = 3, +// }; +// +// enum WiFiMode { +// WM_STATION = 0, +// WM_AP = 1, +// }; +// +// /** Wi-Fi security +// */ +// enum Security { +// // kaizen need to change +// SEC_AUTO = 0, +// SEC_OPEN = 1, +// SEC_WEP = 2, +// SEC_WPA_TKIP = 3, +// SEC_WPA_AES = 4, +// SEC_WPA2_AES = 5, +// SEC_WPA2_TKIP = 6, +// SEC_WPA2_MIXED = 7, +// }; +// +// /** TCP/IP protocol +// */ +// enum Protocol { +// PROTO_UDP = 0, +// PROTO_TCP = 1, +// }; +// +// /** Client/Server +// */ +// enum Type { +// TYPE_CLIENT = 0, +// TYPE_SERVER = 1, +// }; +// +// enum Response { +// RES_NULL, +// RES_MACADDRESS, +// RES_WJOIN, +// RES_CONNECT, +// RES_SSEND, +// RES_FDNS, +// RES_SMGMT, +// RES_WSTATUS, +// +// }; +// +// enum Mode { +// MODE_COMMAND, +// MODE_CMDRESP, +// MODE_DATA_RX, +// MODE_DATA_RXUDP, +// MODE_DATA_RXUDP_BULK, +// }; +// +// enum Status { +// STAT_NONE, +// STAT_READY, +// STAT_STANDBY, +// STAT_WAKEUP, +// STAT_DEEPSLEEP, +// }; +// +// +// WizFi310 (PinName tx, PinName rx, PinName cts, PinName rts, PinName reset, PinName alarm = NC, int baud = 115200); +// +// // --------- WizFi250_at.cpp --------- +// void clearFlags (); +// int sendCommand (const char * cmd, Response res = RES_NULL, int timeout = DEFAULT_WAIT_RESP_TIMEOUT, int opt = 2); +// +// int cmdAT (); +// int cmdMECHO (bool flg); +// int cmdUSET (int baud, char *flow); +// int cmdMMAC (const char *mac = NULL); +// int cmdWSET (WiFiMode mode, const char *ssid, const char *bssid = NULL, int channel = 1); +// int cmdWANT (AntennaMode mode); +// int cmdWNET (bool is_dhcp); +// int cmdWSEC (WiFiMode mode, const char *key, const char *sec = NULL); +// int cmdWJOIN (); +// int cmdWLEAVE (); +// int cmdWSTATUS (); +// int cmdSCON ( const char *openType, const char *socketType, int localPort, const char *dataMode = "0"); +// int cmdSCON ( const char *openType, const char *socketType, const char *remoteIp, int remotePort, int localPort = 0, const char *dataMode = "0"); +// int cmdSSEND ( const char *data, int cid, int sendSize, const char *remoteIp = NULL, int remotePort = 0, int Timeout = 2000 ); +// int cmdCLOSE ( int cid ); +// int cmdFDNS (const char *host); +// int cmdSMGMT ( int cid ); +// +// +// static WizFi310 * getInstance() { +// return _inst; +// }; +// +// +// // --------- WizFi2550_sock.cpp --------- +// int getHostByName (const char * host, char *ip); +// int open (Protocol proto, const char *ip, int remotePort, int localPort = 0, void(*func)(int) = NULL); +// int listen (Protocol proto, int port, void(*func)(int)=NULL); +// int close (int cid); +// void initCon (int cid, bool connected); +// int send (int cid, const char *buf, int len); +// int sendto (int cid, const char *buf, int len, const char *ip, int port); +// int recv (int cid, char *buf, int len); +// int recvfrom (int cid, char *buf, int len, char *ip, int *port); +// int readable (int cid); +// bool isConnected (int cid); +// int accept (int cid); +// int getRemote (int cid, char **ip, int *port); +// +// +//protected: +// static WizFi310 * _inst; +// +// // Serial _wizfi +// RawSerial _wizfi; +// +// int _baud; +// DigitalIn *_cts; +// DigitalOut *_rts; +// int _flow; +// +// DigitalInOut _reset; +// +// struct STATE { +// WiFiMode wm; +// +// //daniel +// //Security sec; +// nsapi_security_t sec; +// char ssid[35]; +// char pass[66]; +// char ip[16]; +// char netmask[16]; +// char gateway[16]; +// char nameserver[16]; +// char mac[18]; +// char resolv[16]; +// char name[32]; +// int rssi; +// bool dhcp; +// time_t time; +// +// bool initialized; +// bool associated; +// volatile Mode mode; +// volatile Status status; +// bool escape; +// volatile bool ok, failure; +// volatile Response res; +// int cid; +// int n; +// CircBuffer<char> *buf; +// } _state; +// +// +//public: +// struct CONNECTION { +// Protocol protocol; +// Type type; +// bool connected; +// char ip[16]; +// int port; +// int send_length; +// int recv_length; +// CircBuffer<char> *buf; +// volatile bool received; +// volatile int parent; +// volatile bool accept; +// void(*func)(int); +// } _con[8]; +// +// // --------- WizFi310.cpp --------- +// +// int join(WiFiMode mode); +// bool isAssociated(); +// +// //int limitedap (); +// //int dissociate (); +// /* +// int disconnect () { +// return dissociate(); +// } +// */ +// +// Status getStatus (); +// +// int setMacAddress (const char *mac); +// int getMacAddress (char *mac); +// int setAddress (const char *name = NULL); +// int setAddress (const char *ip, const char *netmask, const char *gateway, const char *dns = NULL, const char *name = NULL); +// int getAddress (char *ip, char *netmask, char *gateway); +// int setSsid (const char *ssid); +// //daniel +//// int setSec (Security sec, const char *phrase); +// int setSec (nsapi_security_t sec, const char *phrase); +// +// const char* getIPAddress (void); +// const char* getMACAddress (void); +// +// // --------- WizFi250_msg.cpp --------- +// void recvData ( char c ); +// int parseMessage (); +// void msgOk (const char *buf); +// void msgError (const char *buf); +// void msgConnect (const char *buf); +// void msgDisconnect (const char *buf); +// void msgListen (const char *buf); +// //daniel +// void msgMQTTConnect (const char *buf); +// void msgMQTTDisconnect (const char *buf); +// +// void resMacAddress (const char *buf); +// void resWJOIN (const char *buf); +// void resConnect (const char *buf); +// void resSSEND (const char *buf); +// void resFDNS (const char *buf); +// void resSMGMT (const char *buf); +// void resWSTATUS (const char *buf); +// +// +// // --------- WizFi250_hal.cpp --------- +// void setReset (bool flg); +// void isrUart (); +// int getUart (); +// void putUart (char c); +// void setRts (bool flg); +// int lockUart (int ms); +// void unlockUart (); +// void initUart (PinName cts, PinName rts, PinName alarm, int baud); +// +// +// // --------- WizFi2550_util.cpp --------- +// int x2i (char c); +// int i2x (int i); +// +// // --------- WizFi250_ifc.cpp (For NetworkSocketAPI) --------- +// /** +// * Startup the WizFi310 +// * +// * @return true only if WizFi310 was setup correctly +// */ +// bool startup(void); +// +// /** +// * Reset WizFi310 +// * +// * @return true only if WizFi310 resets successfully +// */ +// bool reset(void); +// +// /** +// * Disconnect WizFi310 from AP +// * +// * @return true only if WizFi310 is disconnected successfully +// */ +// bool disconnect(void); +// +// /** +// * Check if WizFi310 is conenected +// * +// * @return true only if the chip has an IP address +// */ +// bool isConnected(void); +// +// +// //daniel for mqtt +// char rcvd_mqtt_topic[128]; +// +//}; + +#endif /* WIZFI250_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WizFi310Interface.cpp Mon Dec 18 23:25:46 2017 +0000 @@ -0,0 +1,321 @@ +/* WizFi310 implementation of NetworkInterfaceAPI + * Copyright (c) 2015 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <string.h> +#include "WizFi310Interface.h" +#include "mbed_debug.h" + +// Various timeouts for different WizFi310 operations +#ifndef WIZFI310_CONNECT_TIMEOUT +#define WIZFI310_CONNECT_TIMEOUT 15000 +#endif +#ifndef WIZFI310_SEND_TIMEOUT +#define WIZFI310_SEND_TIMEOUT 500 +#endif +#ifndef WIZFI310_RECV_TIMEOUT +#define WIZFI310_RECV_TIMEOUT 0 +#endif +#ifndef WIZFI310_MISC_TIMEOUT +#define WIZFI310_MISC_TIMEOUT 500 +#endif +#ifndef WIZFI310_DELAY_MS +#define WIZFI310_DELAY_MS 300 +#endif + +// WizFi310Interface implementation +WizFi310Interface::WizFi310Interface(PinName tx, PinName rx, bool debug) + : _wizfi310(tx, rx, debug) +{ + memset(_ids, 0, sizeof(_ids)); + memset(_cbs, 0, sizeof(_cbs)); + + _wizfi310.attach(this, &WizFi310Interface::event); +} + +int WizFi310Interface::connect(const char *ssid, const char *pass, nsapi_security_t security, + uint8_t channel) +{ + if (channel != 0) { + return NSAPI_ERROR_UNSUPPORTED; + } + + set_credentials(ssid, pass, security); + + return connect(); +} + +int WizFi310Interface::connect() +{ + char sec[10]; + + _wizfi310.setTimeout(WIZFI310_CONNECT_TIMEOUT); + + _wizfi310.startup(0); + + if( !_wizfi310.dhcp(true) ) + { + return NSAPI_ERROR_DHCP_FAILURE; + } + + switch( ap_sec ) + { + case NSAPI_SECURITY_NONE: + strncpy(sec,"OPEN",strlen("OPEN")+1); + break; + case NSAPI_SECURITY_WEP: + strncpy(sec,"WEP",strlen("WEP")+1); + break; + case NSAPI_SECURITY_WPA: + strncpy(sec,"WPA",strlen("WPA")+1); + break; + case NSAPI_SECURITY_WPA2: + strncpy(sec,"WPA2",strlen("WPA2")+1); + break; + case NSAPI_SECURITY_WPA_WPA2: + strncpy(sec,"WPAWPA2",strlen("WPAWPA2")+1); + break; + default: + strncpy(sec,"",strlen("")+1); + break; + } + + if( !(_wizfi310.connect(ap_ssid, ap_pass, sec)) ) + { + return NSAPI_ERROR_NO_CONNECTION; + } + + if( !_wizfi310.getIPAddress() ) + { + return NSAPI_ERROR_DHCP_FAILURE; + } + + return NSAPI_ERROR_OK; +} + + +int WizFi310Interface::set_credentials(const char *ssid, const char *pass, nsapi_security_t security) +{ + memset(ap_ssid, 0, sizeof(ap_ssid)); + strncpy(ap_ssid, ssid, sizeof(ap_ssid)); + + memset(ap_pass, 0, sizeof(ap_pass)); + strncpy(ap_pass, pass, sizeof(ap_pass)); + + ap_sec = security; + return 0; +} + + +int WizFi310Interface::set_channel(uint8_t channel) +{ +} + +int WizFi310Interface::disconnect() +{ + _wizfi310.setTimeout(WIZFI310_MISC_TIMEOUT); + + if (!_wizfi310.disconnect()) + { + return NSAPI_ERROR_DEVICE_ERROR; + } + return NSAPI_ERROR_OK; +} + +const char *WizFi310Interface::get_ip_address() +{ + return _wizfi310.getIPAddress(); +} + +const char *WizFi310Interface::get_mac_address() +{ + return _wizfi310.getMACAddress(); +} + +const char *WizFi310Interface::get_gateway() +{ + return _wizfi310.getGateway(); +} + +const char *WizFi310Interface::get_netmask() +{ + return _wizfi310.getNetmask(); +} + +int8_t WizFi310Interface::get_rssi() +{ + return _wizfi310.getRSSI(); +} + +int WizFi310Interface::scan(WiFiAccessPoint *res, unsigned count) +{ + return _wizfi310.scan(res, count); +} + +struct wizfi310_socket { + int id; + nsapi_protocol_t proto; + bool connected; + SocketAddress addr; +}; + + +int WizFi310Interface::socket_open(void **handle, nsapi_protocol_t proto) +{ + // Look for an unused socket + int id = -1; + + for (int i=0; i<WIZFI310_SOCKET_COUNT; i++) { + if (!_ids[i]){ + id = i; + _ids[i] = true; + break; + } + } + + if (id == -1){ + return NSAPI_ERROR_NO_SOCKET; + } + + struct wizfi310_socket *socket = new struct wizfi310_socket; + if (!socket){ + return NSAPI_ERROR_NO_SOCKET; + } + + socket->id = id; + socket->proto = proto; + socket->connected = false; + *handle = socket; + return 0; +} + +int WizFi310Interface::socket_close(void *handle) +{ + struct wizfi310_socket *socket = (struct wizfi310_socket *)handle; + int err = 0; + _wizfi310.setTimeout(WIZFI310_MISC_TIMEOUT); + + if (socket->connected && !_wizfi310.close(socket->id)) { + err = NSAPI_ERROR_DEVICE_ERROR; + } + + socket->connected = false; + _ids[socket->id] = false; + delete socket; + return err; +} + +int WizFi310Interface::socket_bind(void *handle, const SocketAddress &address) +{ + return NSAPI_ERROR_UNSUPPORTED; +} + +int WizFi310Interface::socket_listen(void *handle, int backlog) +{ + return NSAPI_ERROR_UNSUPPORTED; +} + +int WizFi310Interface::socket_connect(void *handle, const SocketAddress &addr) +{ + struct wizfi310_socket *socket = (struct wizfi310_socket *)handle; + _wizfi310.setTimeout(WIZFI310_MISC_TIMEOUT); + + const char *proto = (socket->proto == NSAPI_UDP) ? "UCN" : "TCN"; + if (!_wizfi310.open(proto, socket->id, addr.get_ip_address(), addr.get_port())) { + return NSAPI_ERROR_DEVICE_ERROR; + } + + socket->connected = true; + return 0; +} + +int WizFi310Interface::socket_accept(void *server, void **socket, SocketAddress *addr) +{ + return NSAPI_ERROR_UNSUPPORTED; +} + +int WizFi310Interface::socket_send(void *handle, const void *data, unsigned size) +{ + struct wizfi310_socket *socket = (struct wizfi310_socket *)handle; + _wizfi310.setTimeout(WIZFI310_SEND_TIMEOUT); + + if (!_wizfi310.send(socket->id, data, size)) { + return NSAPI_ERROR_DEVICE_ERROR; + } + + return size; +} + +int WizFi310Interface::socket_recv(void *handle, void *data, unsigned size) +{ + struct wizfi310_socket *socket = (struct wizfi310_socket *)handle; + _wizfi310.setTimeout(WIZFI310_RECV_TIMEOUT); + + int32_t recv = _wizfi310.recv(socket->id, data, size); + if (recv < 0) { + return NSAPI_ERROR_WOULD_BLOCK; + } + + return recv; +} + +int WizFi310Interface::socket_sendto(void *handle, const SocketAddress &addr, const void *data, unsigned size) +{ + struct wizfi310_socket *socket = (struct wizfi310_socket *)handle; + + if (socket->connected && socket->addr != addr) { + _wizfi310.setTimeout(WIZFI310_MISC_TIMEOUT); + if (!_wizfi310.close(socket->id)) { + return NSAPI_ERROR_DEVICE_ERROR; + } + socket->connected = false; + } + + if (!socket->connected) { + int err = socket_connect(socket, addr); + if (err < 0 ) { + return err; + } + socket->addr = addr; + } + + return socket_send(socket, data, size); +} + +int WizFi310Interface::socket_recvfrom(void *handle, SocketAddress *addr, void *data, unsigned size) +{ + struct wizfi310_socket *socket = (struct wizfi310_socket *)handle; + int ret = socket_recv(socket, data, size); + if (ret >= 0 && addr) { + *addr = socket->addr; + } + + return ret; +} + +void WizFi310Interface::socket_attach(void *handle, void (*callback)(void *), void *data) +{ + struct wizfi310_socket *socket = (struct wizfi310_socket *)handle; + _cbs[socket->id].callback = callback; + _cbs[socket->id].data = data; +} + +void WizFi310Interface::event() +{ + for(int i=0; i<WIZFI310_SOCKET_COUNT; i++){ + if (_cbs[i].callback) { + _cbs[i].callback(_cbs[i].data); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WizFi310Interface.h Mon Dec 18 23:25:46 2017 +0000 @@ -0,0 +1,282 @@ +/* WizFi310 implementation of NetworkInterfaceAPI + * Copyright (c) 2015 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WIZFI310_INTERFACE_H +#define WIZFI310_INTERFACE_H + +#include "WiFiInterface.h" +#include "WizFi310.h" + +#define WIZFI310_SOCKET_COUNT 8 + +#define WIZFI310_RTS_PIN NC +#define WIZFI310_CTS_PIN NC +#define WIZFI310_RESET_PIN NC +#define WIZFI310_ALARM_PIN NC + +/** WizFi310Interface class + * Implementation of the NetworkStack for the WizFi310 + */ +class WizFi310Interface : public NetworkStack, public WiFiInterface +{ +public: + /* WizFi310Interface constructor + */ + + WizFi310Interface(PinName tx, PinName rx, bool debug = true); + //WizFi310Interface(PinName tx, PinName rx, + // PinName rts = WIZFI310_RTS_PIN, PinName cts = WIZFI310_CTS_PIN, + // PinName reset = WIZFI310_RESET_PIN, PinName alarm = WIZFI310_ALARM_PIN, + // int baud=115200 ); + + /** Start the interface + * + * Attempts to connect to a WiFi network. Requires ssid and passphrase to be set. + * If passphrase is invalid, NSAPI_ERROR_AUTH_ERROR is returned. + * + * @return 0 on success, negative error code on failure + */ + virtual int connect(); + + /** Start the interface + * + * Attempts to connect to a WiFi network. + * + * @param ssid Name of the network to connect to + * @param pass Security passphrase to connect to the network + * @param security Type of encryption for connection (Default: NSAPI_SECURITY_NONE) + * @param channel This parameter is not supported, setting it to anything else than 0 will result in NSAPI_ERROR_UNSUPPORTED + * @return 0 on success, or error code on failure + */ + virtual int connect(const char *ssid, const char *pass, nsapi_security_t security = NSAPI_SECURITY_NONE, + uint8_t channel = 0); + + /** Set the WiFi network credentials + * + * @param ssid Name of the network to connect to + * @param pass Security passphrase to connect to the network + * @param security Type of encryption for connection + * (defaults to NSAPI_SECURITY_NONE) + * @return 0 on success, or error code on failure + */ + virtual int set_credentials(const char *ssid, const char *pass, nsapi_security_t security = NSAPI_SECURITY_NONE); + + /** Set the WiFi network channel - NOT SUPPORTED + * + * This function is not supported and will return NSAPI_ERROR_UNSUPPORTED + * + * @param channel Channel on which the connection is to be made, or 0 for any (Default: 0) + * @return Not supported, returns NSAPI_ERROR_UNSUPPORTED + */ + virtual int set_channel(uint8_t channel); + + /** Stop the interface + * @return 0 on success, negative on failure + */ + virtual int disconnect(); + + /** Get the internally stored IP address + * @return IP address of the interface or null if not yet connected + */ + virtual const char *get_ip_address(); + + /** Get the internally stored MAC address + * @return MAC address of the interface + */ + virtual const char *get_mac_address(); + + /** Get the local gateway + * + * @return Null-terminated representation of the local gateway + * or null if no network mask has been recieved + */ + virtual const char *get_gateway(); + + /** Get the local network mask + * + * @return Null-terminated representation of the local network mask + * or null if no network mask has been recieved + */ + virtual const char *get_netmask(); + + /** Gets the current radio signal strength for active connection + * + * @return Connection strength in dBm (negative value) + */ + virtual int8_t get_rssi(); + + /** Scan for available networks + * + * This function will block. + * + * @param ap Pointer to allocated array to store discovered AP + * @param count Size of allocated @a res array, or 0 to only count available AP + * @param timeout Timeout in milliseconds; 0 for no timeout (Default: 0) + * @return Number of entries in @a, or if @a count was 0 number of available networks, negative on error + * see @a nsapi_error + */ + virtual int scan(WiFiAccessPoint *res, unsigned count); + + /** Translates a hostname to an IP address with specific version + * + * The hostname may be either a domain name or an IP address. If the + * hostname is an IP address, no network transactions will be performed. + * + * If no stack-specific DNS resolution is provided, the hostname + * will be resolve using a UDP socket on the stack. + * + * @param address Destination for the host SocketAddress + * @param host Hostname to resolve + * @param version IP version of address to resolve, NSAPI_UNSPEC indicates + * version is chosen by the stack (defaults to NSAPI_UNSPEC) + * @return 0 on success, negative error code on failure + */ + using NetworkInterface::gethostbyname; + + /** Add a domain name server to list of servers to query + * + * @param addr Destination for the host address + * @return 0 on success, negative error code on failure + */ + using NetworkInterface::add_dns_server; + +protected: + /** Open a socket + * @param handle Handle in which to store new socket + * @param proto Type of socket to open, NSAPI_TCP or NSAPI_UDP + * @return 0 on success, negative on failure + */ + virtual int socket_open(void **handle, nsapi_protocol_t proto); + + /** Close the socket + * @param handle Socket handle + * @return 0 on success, negative on failure + * @note On failure, any memory associated with the socket must still + * be cleaned up + */ + virtual int socket_close(void *handle); + + /** Bind a server socket to a specific port + * @param handle Socket handle + * @param address Local address to listen for incoming connections on + * @return 0 on success, negative on failure. + */ + virtual int socket_bind(void *handle, const SocketAddress &address); + + /** Start listening for incoming connections + * @param handle Socket handle + * @param backlog Number of pending connections that can be queued up at any + * one time [Default: 1] + * @return 0 on success, negative on failure + */ + virtual int socket_listen(void *handle, int backlog); + + /** Connects this TCP socket to the server + * @param handle Socket handle + * @param address SocketAddress to connect to + * @return 0 on success, negative on failure + */ + virtual int socket_connect(void *handle, const SocketAddress &address); + + /** Accept a new connection. + * @param handle Handle in which to store new socket + * @param server Socket handle to server to accept from + * @return 0 on success, negative on failure + * @note This call is not-blocking, if this call would block, must + * immediately return NSAPI_ERROR_WOULD_WAIT + */ + virtual int socket_accept(void *handle, void **socket, SocketAddress *address); + + /** Send data to the remote host + * @param handle Socket handle + * @param data The buffer to send to the host + * @param size The length of the buffer to send + * @return Number of written bytes on success, negative on failure + * @note This call is not-blocking, if this call would block, must + * immediately return NSAPI_ERROR_WOULD_WAIT + */ + virtual int socket_send(void *handle, const void *data, unsigned size); + + /** Receive data from the remote host + * @param handle Socket handle + * @param data The buffer in which to store the data received from the host + * @param size The maximum length of the buffer + * @return Number of received bytes on success, negative on failure + * @note This call is not-blocking, if this call would block, must + * immediately return NSAPI_ERROR_WOULD_WAIT + */ + virtual int socket_recv(void *handle, void *data, unsigned size); + + /** Send a packet to a remote endpoint + * @param handle Socket handle + * @param address The remote SocketAddress + * @param data The packet to be sent + * @param size The length of the packet to be sent + * @return The number of written bytes on success, negative on failure + * @note This call is not-blocking, if this call would block, must + * immediately return NSAPI_ERROR_WOULD_WAIT + */ + virtual int socket_sendto(void *handle, const SocketAddress &address, const void *data, unsigned size); + + /** Receive a packet from a remote endpoint + * @param handle Socket handle + * @param address Destination for the remote SocketAddress or null + * @param buffer The buffer for storing the incoming packet data + * If a packet is too long to fit in the supplied buffer, + * excess bytes are discarded + * @param size The length of the buffer + * @return The number of received bytes on success, negative on failure + * @note This call is not-blocking, if this call would block, must + * immediately return NSAPI_ERROR_WOULD_WAIT + */ + virtual int socket_recvfrom(void *handle, SocketAddress *address, void *buffer, unsigned size); + + /** Register a callback on state change of the socket + * @param handle Socket handle + * @param callback Function to call on state change + * @param data Argument to pass to callback + * @note Callback may be called in an interrupt context. + */ + virtual void socket_attach(void *handle, void (*callback)(void *), void *data); + + /** Provide access to the NetworkStack object + * + * @return The underlying NetworkStack object + */ + virtual NetworkStack *get_stack() + { + return this; + } + +private: + WizFi310 _wizfi310; + bool _ids[WIZFI310_SOCKET_COUNT]; + + char ap_ssid[33]; /* 32 is what 802.11 defines as longest possible name; +1 for the \0 */ + nsapi_security_t ap_sec; + uint8_t ap_ch; + char ap_pass[64]; /* The longest allowed passphrase */ + + void event(); + + struct { + void (*callback)(void *); + void *data; + } _cbs[WIZFI310_SOCKET_COUNT]; +}; + +#endif +