diff --git a/README.md b/README.md index 1364edc..0bcaac1 100644 --- a/README.md +++ b/README.md @@ -130,25 +130,27 @@ Different Ameba series are not compatible with each other. Apparently, there isn Note: this list will probably change with each functionality update. -  | `realtek-ambz` ---|-- -Core functions|✔️ -GPIO/PWM/IRQ|✔️/❓/✔️ -Analog input|❓ -UART I/O|✔️ -Flash I/O|❓ -**LIBRARIES** -SPI|❌ -SPIFFS|❌ -Wire|❌ -BLE|- -Wi-Fi|❌ -HTTP|❌ -NTP|❌ -OTA|❌ -MDNS|❌ -MQTT|❌ -SD|❌ +  | `realtek-ambz` +--------------------|--------------- +Core functions | ✔️ +GPIO/PWM/IRQ | ✔️/❓/✔️ +Analog input | ❓ +UART I/O | ✔️ +Flash I/O | ❓ +**CORE LIBRARIES** | +SoftwareSerial | ❌ +SPI | ❌ +Wire | ❌ +**OTHER LIBRARIES** | +SPIFFS | ❌ +BLE | - +Wi-Fi (SSL) | ✔️ (❌) +HTTP | ❌ +NTP | ❌ +OTA | ❌ +MDNS | ❌ +MQTT | ❌ +SD | ❌ Legend: - ✔️ working diff --git a/arduino/realtek-ambz/libraries/WiFi/library.properties b/arduino/realtek-ambz/libraries/WiFi/library.properties new file mode 100644 index 0000000..d4dce64 --- /dev/null +++ b/arduino/realtek-ambz/libraries/WiFi/library.properties @@ -0,0 +1,9 @@ +name=WiFi +version=1.0.1 +author=Realtek +maintainer=Realtek +sentence=Enables network connection (local and Internet). +paragraph=With this library you can instantiate Servers, Clients and send/receive UDP packets through WiFi. +category=Communication +url=http://www.amebaiot.com/ameba-arduino-peripherals-examples/ +architectures=Ameba1 diff --git a/arduino/realtek-ambz/libraries/WiFi/src/WiFi.cpp b/arduino/realtek-ambz/libraries/WiFi/src/WiFi.cpp new file mode 100644 index 0000000..0aeeb8e --- /dev/null +++ b/arduino/realtek-ambz/libraries/WiFi/src/WiFi.cpp @@ -0,0 +1,203 @@ +/* + WiFi.cpp - Library for Arduino Wifi shield. + Copyright (c) 2011-2014 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "WiFi.h" + +#include + +#include "wifi_drv.h" + +WiFiClass::WiFiClass() { +} + +void WiFiClass::init() { + WiFiDrv::wifiDriverInit(); +} + +char* WiFiClass::firmwareVersion() { + return WiFiDrv::getFwVersion(); +} + +int WiFiClass::begin(char* ssid) { + uint8_t status = WL_IDLE_STATUS; + + WiFiDrv::wifiDriverInit(); + + if (WiFiDrv::wifiSetNetwork(ssid, strlen(ssid)) != WL_FAILURE) { + status = WiFiDrv::getConnectionStatus(); + } else { + status = WL_CONNECT_FAILED; + } + return status; +} + +int WiFiClass::begin(char* ssid, uint8_t key_idx, const char *key) { + uint8_t status = WL_IDLE_STATUS; + + WiFiDrv::wifiDriverInit(); + + // set encryption key + if (WiFiDrv::wifiSetKey(ssid, strlen(ssid), key_idx, key, strlen(key)) != WL_FAILURE) { + status = WiFiDrv::getConnectionStatus(); + } else { + status = WL_CONNECT_FAILED; + } + return status; +} + +int WiFiClass::begin(char* ssid, const char *passphrase) { + uint8_t status = WL_IDLE_STATUS; + + WiFiDrv::wifiDriverInit(); + + // set passphrase + if (WiFiDrv::wifiSetPassphrase(ssid, strlen(ssid), passphrase, strlen(passphrase))!= WL_FAILURE) { + status = WiFiDrv::getConnectionStatus(); + } else { + status = WL_CONNECT_FAILED; + } + return status; +} + +int WiFiClass::disconnect() { + return WiFiDrv::disconnect(); +} + +uint8_t* WiFiClass::macAddress(uint8_t* mac) { + uint8_t* _mac = WiFiDrv::getMacAddress(); + memcpy(mac, _mac, WL_MAC_ADDR_LENGTH); + return mac; +} + +IPAddress WiFiClass::localIP() { + IPAddress ret; + WiFiDrv::getIpAddress(ret); + return ret; +} + +IPAddress WiFiClass::subnetMask() { + IPAddress ret; + WiFiDrv::getSubnetMask(ret); + return ret; +} + +IPAddress WiFiClass::gatewayIP() { + IPAddress ret; + WiFiDrv::getGatewayIP(ret); + return ret; +} + +char* WiFiClass::SSID() { + return WiFiDrv::getCurrentSSID(); +} + +uint8_t* WiFiClass::BSSID(uint8_t* bssid) { + uint8_t* _bssid = WiFiDrv::getCurrentBSSID(); + memcpy(bssid, _bssid, WL_MAC_ADDR_LENGTH); + return bssid; +} + +int32_t WiFiClass::RSSI() { + return WiFiDrv::getCurrentRSSI(); +} + +uint8_t WiFiClass::encryptionType() { + return WiFiDrv::getCurrentEncryptionType(); +} + + +int8_t WiFiClass::scanNetworks() { + uint8_t attempts = 10; + uint8_t numOfNetworks = 0; + + if (WiFiDrv::startScanNetworks() == WL_FAILURE) { + return WL_FAILURE; + } + do { + delay(2000); + numOfNetworks = WiFiDrv::getScanNetworks(); + } while (( numOfNetworks == 0)&&(--attempts>0)); + return numOfNetworks; +} + +char* WiFiClass::SSID(uint8_t networkItem) { + return WiFiDrv::getSSIDNetoworks(networkItem); +} + +int32_t WiFiClass::RSSI(uint8_t networkItem) { + return WiFiDrv::getRSSINetoworks(networkItem); +} + +uint8_t WiFiClass::encryptionType(uint8_t networkItem) { + return WiFiDrv::getEncTypeNetowrks(networkItem); +} + +uint32_t WiFiClass::encryptionTypeEx(uint8_t networkItem) { + return WiFiDrv::getEncTypeNetowrksEx(networkItem); +} + +uint8_t WiFiClass::status() { + return WiFiDrv::getConnectionStatus(); +} + +int WiFiClass::hostByName(const char* aHostname, IPAddress& aResult) { + return WiFiDrv::getHostByName(aHostname, aResult); +} + +int WiFiClass::apbegin(char* ssid, char* channel) { + uint8_t status = WL_IDLE_STATUS; + + if (WiFiDrv::apSetNetwork(ssid, strlen(ssid)) != WL_FAILURE) { + WiFiDrv::apSetChannel(channel); + + if (WiFiDrv::apActivate() != WL_FAILURE) { + status = WL_CONNECTED; + } else { + status = WL_CONNECT_FAILED; + } + } else { + status = WL_CONNECT_FAILED; + } + return status; +} + +int WiFiClass::apbegin(char* ssid, char* password, char* channel) { + uint8_t status = WL_IDLE_STATUS; + + if (WiFiDrv::apSetNetwork(ssid, strlen(ssid)) != WL_FAILURE) { + WiFiDrv::apSetPassphrase(password, strlen(password)); + WiFiDrv::apSetChannel(channel); + + if(WiFiDrv::apActivate() != WL_FAILURE) { + status = WL_CONNECTED; + } else { + status = WL_CONNECT_FAILED; + } + } else { + status = WL_CONNECT_FAILED; + } + + return status; +} + +int WiFiClass::disablePowerSave() { + return WiFiDrv::disablePowerSave(); +} + +WiFiClass WiFi; diff --git a/arduino/realtek-ambz/libraries/WiFi/src/WiFi.h b/arduino/realtek-ambz/libraries/WiFi/src/WiFi.h new file mode 100644 index 0000000..22fb301 --- /dev/null +++ b/arduino/realtek-ambz/libraries/WiFi/src/WiFi.h @@ -0,0 +1,255 @@ +/* + WiFi.h - Library for Arduino Wifi shield. + Copyright (c) 2011-2014 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef WiFi_h +#define WiFi_h + +#include "Arduino.h" +#include + +extern "C" { + #include "wl_definitions.h" + #include "wl_types.h" +} + +#include "WiFiClient.h" +#include "WiFiServer.h" +#include "WiFiSSLClient.h" + +class WiFiClass +{ + private: + static void init(); + + public: + + WiFiClass(); + + /* + * Get firmware version + */ + static char* firmwareVersion(); + + /* Start Wifi connection for OPEN networks + * + * param ssid: Pointer to the SSID string. + */ + int begin(char* ssid); + + /* Start Wifi connection with WEP encryption. + * Configure a key into the device. The key type (WEP-40, WEP-104) + * is determined by the size of the key (5 bytes for WEP-40, 13 bytes for WEP-104). + * + * param ssid: Pointer to the SSID string. + * param key_idx: The key index to set. Valid values are 0-3. + * param key: Key input buffer. + */ + int begin(char* ssid, uint8_t key_idx, const char* key); + + /* Start Wifi connection with passphrase + * the most secure supported mode will be automatically selected + * + * param ssid: Pointer to the SSID string. + * param passphrase: Passphrase. Valid characters in a passphrase + * must be between ASCII 32-126 (decimal). + */ + int begin(char* ssid, const char *passphrase); + + /* Change Ip configuration settings disabling the dhcp client + * + * param local_ip: Static ip configuration + */ + void config(IPAddress local_ip); + + /* Change Ip configuration settings disabling the dhcp client + * + * param local_ip: Static ip configuration + * param dns_server: IP configuration for DNS server 1 + */ + void config(IPAddress local_ip, IPAddress dns_server); + + /* Change Ip configuration settings disabling the dhcp client + * + * param local_ip: Static ip configuration + * param dns_server: IP configuration for DNS server 1 + * param gateway : Static gateway configuration + */ + void config(IPAddress local_ip, IPAddress dns_server, IPAddress gateway); + + /* Change Ip configuration settings disabling the dhcp client + * + * param local_ip: Static ip configuration + * param dns_server: IP configuration for DNS server 1 + * param gateway: Static gateway configuration + * param subnet: Static Subnet mask + */ + void config(IPAddress local_ip, IPAddress dns_server, IPAddress gateway, IPAddress subnet); + + /* Change DNS Ip configuration + * + * param dns_server1: ip configuration for DNS server 1 + */ + void setDNS(IPAddress dns_server1); + + /* Change DNS Ip configuration + * + * param dns_server1: ip configuration for DNS server 1 + * param dns_server2: ip configuration for DNS server 2 + * + */ + void setDNS(IPAddress dns_server1, IPAddress dns_server2); + + /* + * Disconnect from the network + * + * return: one value of wl_status_t enum + */ + int disconnect(void); + + /* + * Get the interface MAC address. + * + * return: pointer to uint8_t array with length WL_MAC_ADDR_LENGTH + */ + uint8_t* macAddress(uint8_t* mac); + + /* + * Get the interface IP address. + * + * return: Ip address value + */ + IPAddress localIP(); + + /* + * Get the interface subnet mask address. + * + * return: subnet mask address value + */ + IPAddress subnetMask(); + + /* + * Get the gateway ip address. + * + * return: gateway ip address value + */ + IPAddress gatewayIP(); + + /* + * Return the current SSID associated with the network + * + * return: ssid string + */ + char* SSID(); + + /* + * Return the current BSSID associated with the network. + * It is the MAC address of the Access Point + * + * return: pointer to uint8_t array with length WL_MAC_ADDR_LENGTH + */ + uint8_t* BSSID(uint8_t* bssid); + + /* + * Return the current RSSI /Received Signal Strength in dBm) + * associated with the network + * + * return: signed value + */ + int32_t RSSI(); + + /* + * Return the Encryption Type associated with the network + * + * return: one value of wl_enc_type enum + */ + uint8_t encryptionType(); + + /* + * Start scan WiFi networks available + * + * return: Number of discovered networks + */ + int8_t scanNetworks(); + + /* + * Return the SSID discovered during the network scan. + * + * param networkItem: specify from which network item want to get the information + * + * return: ssid string of the specified item on the networks scanned list + */ + char* SSID(uint8_t networkItem); + + /* + * Return the encryption type of the networks discovered during the scanNetworks + * + * param networkItem: specify from which network item want to get the information + * + * return: encryption type (enum wl_enc_type) of the specified item on the networks scanned list + */ + uint8_t encryptionType(uint8_t networkItem); + + /* + * Return the security type and encryption type of the networks discovered during the scanNetworks + * + * param networkItem: specify from which network item want to get the information + * + * return: security and encryption type of the specified item on the networks scanned list + */ + uint32_t encryptionTypeEx(uint8_t networkItem); + + /* + * Return the RSSI of the networks discovered during the scanNetworks + * + * param networkItem: specify from which network item want to get the information + * + * return: signed value of RSSI of the specified item on the networks scanned list + */ + int32_t RSSI(uint8_t networkItem); + + /* + * Return Connection status. + * + * return: one of the value defined in wl_status_t + */ + uint8_t status(); + + /* + * Resolve the given hostname to an IP address. + * param aHostname: Name to be resolved + * param aResult: IPAddress structure to store the returned IP address + * result: 1 if aIPAddrString was successfully converted to an IP address, + * else error code + */ + int hostByName(const char* aHostname, IPAddress& aResult); + + int apbegin(char* ssid, char* channel); + + int apbegin(char* ssid, char* password, char* channel); + + int disablePowerSave(); + + friend class WiFiClient; + friend class WiFiServer; + friend class WiFiSSLClient; +}; + +extern WiFiClass WiFi; + +#endif diff --git a/arduino/realtek-ambz/libraries/WiFi/src/WiFiClient.cpp b/arduino/realtek-ambz/libraries/WiFi/src/WiFiClient.cpp new file mode 100644 index 0000000..b3aaa78 --- /dev/null +++ b/arduino/realtek-ambz/libraries/WiFi/src/WiFiClient.cpp @@ -0,0 +1,191 @@ + +extern "C" { + #include "wl_definitions.h" + #include "wl_types.h" + #include "string.h" + #include "errno.h" + #include "update.h" +} + +#include "WiFi.h" +#include "WiFiClient.h" +#include "WiFiServer.h" +#include "server_drv.h" + +WiFiClient::WiFiClient() : _sock(MAX_SOCK_NUM) { + _is_connected = false; + recvTimeout = 3000; +} + +WiFiClient::WiFiClient(uint8_t sock) { + _sock = sock; + if(sock >= 0 && sock != 0xFF) { + _is_connected = true; + } + recvTimeout = 3000; +} + +uint8_t WiFiClient::connected() { + if ((_sock < 0) || (_sock == 0xFF)) { + _is_connected = false; + return 0; + } else { + if (_is_connected) { + return 1; + } else { + stop(); + return 0; + } + } +} + +int WiFiClient::available() { + int ret = 0; + int err; + + if( !_is_connected) { + return 0; + } + if (_sock >= 0) { + ret = clientdrv.availData(_sock); + if (ret > 0) { + return 1; + } else { + err = clientdrv.getLastErrno(_sock); + if (err != EAGAIN) { + _is_connected = false; + } + return 0; + } + } +} + +int WiFiClient::read() { + int ret; + int err; + uint8_t b[1]; + + if (!available()) { + return -1; + } + + ret = clientdrv.getData(_sock, b); + if (ret > 0) { + return b[0]; + } else { + err = clientdrv.getLastErrno(_sock); + if (err != EAGAIN) { + _is_connected = false; + } + } + + return ret; +} + +int WiFiClient::read(uint8_t* buf, size_t size) { + uint16_t _size = size; + int ret; + int err; + + ret = clientdrv.getDataBuf(_sock, buf, _size); + if (ret <= 0) { + err = clientdrv.getLastErrno(_sock); + if (err != EAGAIN) { + _is_connected = false; + } + } + return ret; +} + +void WiFiClient::stop() { + if (_sock < 0) { + return; + } + + clientdrv.stopClient(_sock); + _is_connected = false; + + _sock = -1; +} + +size_t WiFiClient::write(uint8_t b) { + return write(&b, 1); +} + +size_t WiFiClient::write(const uint8_t *buf, size_t size) { + if (_sock < 0) { + setWriteError(); + return 0; + } + if (size==0) { + setWriteError(); + return 0; + } + + if (!clientdrv.sendData(_sock, buf, size)) { + setWriteError(); + _is_connected = false; + return 0; + } + + return size; +} + +WiFiClient::operator bool() { + return _sock >= 0; +} + +int WiFiClient::connect(const char* host, uint16_t port) { + IPAddress remote_addr; + + if (WiFi.hostByName(host, remote_addr)) { + return connect(remote_addr, port); + } + return 0; +} + +int WiFiClient::connect(IPAddress ip, uint16_t port) { + _is_connected = false; + + _sock = clientdrv.startClient(ip, port); + + if (_sock < 0) { + _is_connected = false; + return 0; + } else { + _is_connected = true; + clientdrv.setSockRecvTimeout(_sock, recvTimeout); + } + + return 1; +} + +int WiFiClient::peek() { + uint8_t b; + + if (!available()) { + return -1; + } + + clientdrv.getData(_sock, &b, 1); + return b; +} + +void WiFiClient::flush() { + while (available()) { + read(); + } +} + +// extend API from RTK + +int WiFiClient::setRecvTimeout(int timeout) { + if (connected()) { + recvTimeout = timeout; + clientdrv.setSockRecvTimeout(_sock, recvTimeout); + } +} + +int WiFiClient::read(char *buf, size_t size) { + read((uint8_t *)buf, size); +} diff --git a/arduino/realtek-ambz/libraries/WiFi/src/WiFiClient.h b/arduino/realtek-ambz/libraries/WiFi/src/WiFiClient.h new file mode 100644 index 0000000..642f58e --- /dev/null +++ b/arduino/realtek-ambz/libraries/WiFi/src/WiFiClient.h @@ -0,0 +1,55 @@ +#ifndef wificlient_h +#define wificlient_h + +#include "Arduino.h" +#include "api/Client.h" +#include "server_drv.h" + +class WiFiClient : public Client { + public: + WiFiClient(); + WiFiClient(uint8_t sock); + + uint8_t status(); + virtual int connect(IPAddress ip, uint16_t port); + virtual int connect(const char *host, uint16_t port); + virtual size_t write(uint8_t); + virtual size_t write(const uint8_t *buf, size_t size); + virtual int available(); + virtual int read(); + virtual int read(uint8_t *buf, size_t size); + virtual int peek(); + virtual void flush(); + virtual void stop(); + virtual uint8_t connected(); + virtual operator bool(); + + friend class WiFiServer; + + using Print::write; + + // extend API from RTK + + int setRecvTimeout(int timeout); + int read(char *buf, size_t size); + + private: + int _sock; + ServerDrv clientdrv; + bool _is_connected; + uint8_t data[DATA_LENTH]; + + int recvTimeout; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +extern int update_ota_local(char *ip, int port); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/arduino/realtek-ambz/libraries/WiFi/src/WiFiSSLClient.cpp b/arduino/realtek-ambz/libraries/WiFi/src/WiFiSSLClient.cpp new file mode 100644 index 0000000..e79e87a --- /dev/null +++ b/arduino/realtek-ambz/libraries/WiFi/src/WiFiSSLClient.cpp @@ -0,0 +1,271 @@ +#include "WiFi.h" +#include "WiFiSSLClient.h" + +extern "C" { + #include "wl_definitions.h" + #include "wl_types.h" + #include "string.h" + #include "errno.h" +} + +WiFiSSLClient::WiFiSSLClient() { + _is_connected = false; + _sock = -1; + + sslclient.socket = -1; + sslclient.ssl = NULL; + sslclient.recvTimeout = 3000; + + _rootCABuff = NULL; + _cli_cert = NULL; + _cli_key = NULL; + _psKey = NULL; + _pskIdent = NULL; + _sni_hostname = NULL; +} + +WiFiSSLClient::WiFiSSLClient(uint8_t sock) { + _sock = sock; + + sslclient.socket = -1; + sslclient.ssl = NULL; + sslclient.recvTimeout = 3000; + +// if(sock >= 0) { +// _is_connected = true; +// } + _is_connected = true; + + _rootCABuff = NULL; + _cli_cert = NULL; + _cli_key = NULL; + _psKey = NULL; + _pskIdent = NULL; + _sni_hostname = NULL; +} + +uint8_t WiFiSSLClient::connected() { + if (sslclient.socket < 0) { + _is_connected = false; + return 0; + } else { + if (_is_connected) { + return 1; + } else { + stop(); + return 0; + } + } +} + +int WiFiSSLClient::available() { + int ret = 0; + int err; + + if (!_is_connected) { + return 0; + } + if (sslclient.socket >= 0) { + ret = ssldrv.availData(&sslclient); + if (ret > 0) { + return 1; + } else { + err = ssldrv.getLastErrno(&sslclient); + if ((err > 0) && (err != EAGAIN)) { + _is_connected = false; + } + } + return 0; + } + + return 0; +} + +int WiFiSSLClient::read() { + int ret; + int err; + uint8_t b[1]; + + if (!available()) { + return -1; + } + + ret = ssldrv.getData(&sslclient, b); + if (ret > 0) { + return b[0]; + } else { + err = ssldrv.getLastErrno(&sslclient); + if ((err > 0) && (err != EAGAIN)) { + _is_connected = false; + } + } + return -1; +} + +int WiFiSSLClient::read(uint8_t* buf, size_t size) { + uint16_t _size = size; + int ret; + int err; + + ret = ssldrv.getDataBuf(&sslclient, buf, _size); + if (ret <= 0) { + err = ssldrv.getLastErrno(&sslclient); + if ((err > 0) && (err != EAGAIN)) { + _is_connected = false; + } + } + return ret; +} + +void WiFiSSLClient::stop() { + + if (sslclient.socket < 0) { + return; + } + + ssldrv.stopClient(&sslclient); + _is_connected = false; + + sslclient.socket = -1; + _sock = -1; +} + +size_t WiFiSSLClient::write(uint8_t b) { + return write(&b, 1); +} + +size_t WiFiSSLClient::write(const uint8_t *buf, size_t size) { + if (sslclient.socket < 0) { + setWriteError(); + return 0; + } + if (size == 0) { + setWriteError(); + return 0; + } + + if (!ssldrv.sendData(&sslclient, buf, size)) { + setWriteError(); + _is_connected = false; + return 0; + } + + return size; +} + +WiFiSSLClient::operator bool() { + return (sslclient.socket >= 0); +} + +int WiFiSSLClient::connect(IPAddress ip, uint16_t port) { + if (_psKey != NULL && _pskIdent != NULL) + return connect(ip, port, _pskIdent, _psKey); + return connect(ip, port, _rootCABuff, _cli_cert, _cli_key); +} + +int WiFiSSLClient::connect(const char *host, uint16_t port) { + + if (_sni_hostname == NULL) { + _sni_hostname = (char*)host; + } + + if (_psKey != NULL && _pskIdent != NULL) + return connect(host, port, _pskIdent, _psKey); + return connect(host, port, _rootCABuff, _cli_cert, _cli_key); +} + +int WiFiSSLClient::connect(const char* host, uint16_t port, unsigned char* rootCABuff, unsigned char* cli_cert, unsigned char* cli_key) { + IPAddress remote_addr; + + if (_sni_hostname == NULL) { + _sni_hostname = (char*)host; + } + + if (WiFi.hostByName(host, remote_addr)) { + return connect(remote_addr, port, rootCABuff, cli_cert, cli_key); + } + return 0; +} + +int WiFiSSLClient::connect(IPAddress ip, uint16_t port, unsigned char* rootCABuff, unsigned char* cli_cert, unsigned char* cli_key) { + int ret = 0; + + ret = ssldrv.startClient(&sslclient, uint32_t(ip), port, rootCABuff, cli_cert, cli_key, NULL, NULL, _sni_hostname); + + if (ret < 0) { + _is_connected = false; + return 0; + } else { + _is_connected = true; + } + + return 1; +} + +int WiFiSSLClient::connect(const char *host, uint16_t port, unsigned char* pskIdent, unsigned char* psKey) { + IPAddress remote_addr; + + if (_sni_hostname == NULL) { + _sni_hostname = (char*)host; + } + + if (WiFi.hostByName(host, remote_addr)) { + return connect(remote_addr, port, pskIdent, psKey); + } + return 0; +} + +int WiFiSSLClient::connect(IPAddress ip, uint16_t port, unsigned char* pskIdent, unsigned char* psKey) { + int ret = 0; + + ret = ssldrv.startClient(&sslclient, uint32_t(ip), port, NULL, NULL, NULL, pskIdent, psKey, _sni_hostname); + + if (ret < 0) { + _is_connected = false; + return 0; + } else { + _is_connected = true; + } + + return 1; +} + +int WiFiSSLClient::peek() { + uint8_t b; + + if (!available()) { + return -1; + } + + ssldrv.getData(&sslclient, &b, 1); + + return b; +} +void WiFiSSLClient::flush() { + while (available()) { + read(); + } +} + +void WiFiSSLClient::setRootCA(unsigned char *rootCA) { + _rootCABuff = rootCA; +} + +void WiFiSSLClient::setClientCertificate(unsigned char *client_ca, unsigned char *private_key) { + _cli_cert = client_ca; + _cli_key = private_key; +} + +void WiFiSSLClient::setPreSharedKey(unsigned char *pskIdent, unsigned char *psKey) { + _psKey = psKey; + _pskIdent = pskIdent; +} + +int WiFiSSLClient::setRecvTimeout(int timeout) { + sslclient.recvTimeout = timeout; + if (connected()) { + ssldrv.setSockRecvTimeout(sslclient.socket, sslclient.recvTimeout); + } + + return 0; +} diff --git a/arduino/realtek-ambz/libraries/WiFi/src/WiFiSSLClient.h b/arduino/realtek-ambz/libraries/WiFi/src/WiFiSSLClient.h new file mode 100644 index 0000000..c4514ec --- /dev/null +++ b/arduino/realtek-ambz/libraries/WiFi/src/WiFiSSLClient.h @@ -0,0 +1,55 @@ +#ifndef wifisslclient_h +#define wifisslclient_h + +#include "Arduino.h" +#include "api/Client.h" +#include "ssl_drv.h" + +struct mbedtls_ssl_context; +class WiFiSSLClient : public Client { + + public: + WiFiSSLClient(); + WiFiSSLClient(uint8_t sock); + + uint8_t status(); + virtual int connect(IPAddress ip, uint16_t port); + virtual int connect(const char *host, uint16_t port); + virtual size_t write(uint8_t); + virtual size_t write(const uint8_t *buf, size_t size); + virtual int available(); + virtual int read(); + virtual int read(uint8_t *buf, size_t size); + virtual int peek(); + virtual void flush(); + virtual void stop(); + virtual uint8_t connected(); + virtual operator bool(); + + void setRootCA(unsigned char *rootCA); + void setClientCertificate(unsigned char *client_ca, unsigned char *private_key); + void setPreSharedKey(unsigned char *pskIdent, unsigned char *psKey); // psKey expressed as hexadecimal string + + int connect(const char *host, uint16_t port, unsigned char* rootCABuff, unsigned char* cli_cert, unsigned char* cli_key); + int connect(IPAddress ip, uint16_t port, unsigned char* rootCABuff, unsigned char* cli_cert, unsigned char* cli_key); + int connect(const char *host, uint16_t port, unsigned char* pskIdent, unsigned char* psKey); + int connect(IPAddress ip, uint16_t port, unsigned char* pskIdent, unsigned char* psKey); + + using Print::write; + int setRecvTimeout(int timeout); + + private: + int _sock; + bool _is_connected; + sslclient_context sslclient; + SSLDrv ssldrv; + + unsigned char *_rootCABuff; + unsigned char *_cli_cert; + unsigned char *_cli_key; + unsigned char *_psKey; + unsigned char *_pskIdent; + char *_sni_hostname; +}; + +#endif diff --git a/arduino/realtek-ambz/libraries/WiFi/src/WiFiServer.cpp b/arduino/realtek-ambz/libraries/WiFi/src/WiFiServer.cpp new file mode 100644 index 0000000..1553d35 --- /dev/null +++ b/arduino/realtek-ambz/libraries/WiFi/src/WiFiServer.cpp @@ -0,0 +1,88 @@ +/* + WiFiServer.cpp - Library for Arduino Wifi shield. + Copyright (c) 2011-2014 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +#include "server_drv.h" +#include "WiFi.h" +#include "WiFiClient.h" +#include "WiFiServer.h" + +WiFiServer::WiFiServer(uint16_t port) { + _port = port; +} + +void WiFiServer::begin() { + _sock_ser = serverfd.startServer(_port); +} + +WiFiClient WiFiServer::available(uint8_t* status) { + int client_fd; + + client_fd = serverfd.getAvailable(_sock_ser); + + return WiFiClient(client_fd); +} + +size_t WiFiServer::write(uint8_t b) { + return write(&b, 1); +} + +size_t WiFiServer::write(const uint8_t *buf, size_t size) { + if (_sock_ser < 0) { + setWriteError(); + return 0; + } + if (size == 0) { + setWriteError(); + return 0; + } + + if (!serverfd.sendData(_sock_ser, buf, size)) { + setWriteError(); + return 0; + } + + return size; +} + +#if 0 +uint8_t WiFiServer::status() { + return ServerDrv::getServerState(0); +} + + +size_t WiFiServer::write(uint8_t b) { + return write(&b, 1); +} + +size_t WiFiServer::write(const uint8_t *buffer, size_t size) { + size_t n = 0; + + for (int sock = 0; sock < MAX_SOCK_NUM; sock++) { + if (WiFiClass::_server_port[sock] != 0) { + WiFiClient client(sock); + + if ((WiFiClass::_server_port[sock] == _port) && (client.status() == ESTABLISHED)) { + n+=client.write(buffer, size); + } + } + } + return n; +} +#endif diff --git a/arduino/realtek-ambz/libraries/WiFi/src/WiFiServer.h b/arduino/realtek-ambz/libraries/WiFi/src/WiFiServer.h new file mode 100644 index 0000000..aade21e --- /dev/null +++ b/arduino/realtek-ambz/libraries/WiFi/src/WiFiServer.h @@ -0,0 +1,29 @@ +#ifndef wifiserver_h +#define wifiserver_h + +#include "Arduino.h" +#include "api/Server.h" +#include "server_drv.h" + +class WiFiClient; + +class WiFiServer : public Server { + private: + uint16_t _port; + int _sock_ser; + ServerDrv serverfd; + + public: + WiFiServer(uint16_t); + + WiFiClient available(uint8_t* status = NULL); + + void begin(); + virtual size_t write(uint8_t b); + virtual size_t write(const uint8_t *buf, size_t size); + //uint8_t status(); + + using Print::write; +}; + +#endif diff --git a/arduino/realtek-ambz/libraries/WiFi/src/WiFiUdp.cpp b/arduino/realtek-ambz/libraries/WiFi/src/WiFiUdp.cpp new file mode 100644 index 0000000..805cdbc --- /dev/null +++ b/arduino/realtek-ambz/libraries/WiFi/src/WiFiUdp.cpp @@ -0,0 +1,192 @@ +/* + WiFiUdp.cpp - Library for Arduino Wifi shield. + Copyright (c) 2011-2014 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifdef __cplusplus +extern "C" { + +extern int rtl_printf(const char *fmt, ...); + +} +#endif + +#include +#include "server_drv.h" +#include "wifi_drv.h" +#include "WiFi.h" +#include "WiFiUdp.h" +#include "WiFiClient.h" +#include "WiFiServer.h" + +/* Constructor */ +WiFiUDP::WiFiUDP() : _sock(-1), _client_sock(-1) {} + +/* Start WiFiUDP socket, listening at local port PORT */ +uint8_t WiFiUDP::begin(uint16_t port) { + if (_port == port && _sock >= 0) { + return 1; + } + + _port = port; + _sock = serverDrv.startServer(port, UDP_MODE); + + if (_sock >=0 ) { + return 1; + } + + return 0; +} + +/* return number of bytes available in the current packet, + will return zero if parsePacket hasn't been called yet */ +int WiFiUDP::available() { + int ret; + + if (_sock >= 0) { + ret = serverDrv.availData(_sock); + if (ret > 0) { + return ret; + } else { + return 0; + } + } + return 0; +} + +/* Release any resources being used by this WiFiUDP instance */ +void WiFiUDP::stop() { + if (_sock < 0) { + return; + } + serverDrv.stopClient(_sock); + _sock = -1; +} + +int WiFiUDP::beginPacket(const char *host, uint16_t port) { + // Look up the host first + int ret = 0; + IPAddress remote_addr; + if (WiFi.hostByName(host, remote_addr)) { + return beginPacket(remote_addr, port); + } + return ret; +} + +int WiFiUDP::beginPacket(IPAddress ip, uint16_t port) { + peer_ip = ip; + peer_port = port; + + if (_sock >= 0) { + _client_sock = _sock; + } else { + _client_sock = serverDrv.startClient(ip, port, UDP_MODE); + } + + if (_client_sock < 0) { + return 0; + } else { + return 1; + } +} + +int WiFiUDP::endPacket() { + if (_client_sock >= 0 && _client_sock != _sock) { + serverDrv.stopClient(_client_sock); + } + + peer_ip = 0; + peer_port = 0; + _client_sock = -1; + + return true; +} + +size_t WiFiUDP::write(uint8_t byte) { + return write(&byte, 1); +} + +size_t WiFiUDP::write(const uint8_t *buffer, size_t size) { + writeImmediately(buffer, size); + return size; +} + +size_t WiFiUDP::writeImmediately(const uint8_t *buffer, size_t size) { + serverDrv.sendtoData(_client_sock, buffer, size, peer_ip, peer_port); + return size; +} + +int WiFiUDP::parsePacket() { + return available(); +} + +int WiFiUDP::read() { + int ret; + uint8_t b; + + ret = serverDrv.getData(_sock, &b); + if (ret == 1) { + return b; + } else { + return ret; + } +} + +int WiFiUDP::read(unsigned char* buffer, size_t len) { + return serverDrv.getDataBuf(_sock, buffer, len); +} + +int WiFiUDP::peek() { + uint8_t b; + if (!available()) { + return -1; + } + + serverDrv.getData(_sock, &b, 1); + return b; +} + +void WiFiUDP::flush() { + while (read() > 0); +} + +IPAddress WiFiUDP::remoteIP() { + uint32_t _remoteIp; + uint16_t _remotePort; + + serverDrv.getRemoteData(_sock, &_remoteIp, &_remotePort); + + IPAddress ip(_remoteIp); + return ip; +} + +uint16_t WiFiUDP::remotePort() { + uint32_t _remoteIp; + uint16_t _remotePort; + + serverDrv.getRemoteData(_sock, &_remoteIp, &_remotePort); + + return _remotePort; +} + +// extend API by RTK + +void WiFiUDP::setRecvTimeout(int timeout) { + if (_sock >= 0) { + serverDrv.setSockRecvTimeout(_sock, timeout); + } +} diff --git a/arduino/realtek-ambz/libraries/WiFi/src/WiFiUdp.h b/arduino/realtek-ambz/libraries/WiFi/src/WiFiUdp.h new file mode 100644 index 0000000..75301d6 --- /dev/null +++ b/arduino/realtek-ambz/libraries/WiFi/src/WiFiUdp.h @@ -0,0 +1,95 @@ +/* + WiFiUdp.h - Library for Arduino Wifi shield. + Copyright (c) 2011-2014 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef wifiudp_h +#define wifiudp_h + +#include "Arduino.h" +#include + +#include "server_drv.h" + +#define UDP_TX_PACKET_MAX_SIZE 24 + +class WiFiUDP : public UDP { + private: + int _sock; // socket ID + uint16_t _port; // local port to listen on + ServerDrv serverDrv; // socket driver + + int _client_sock; + uint32_t peer_ip; + uint32_t peer_port; + + public: + WiFiUDP(); // Constructor + virtual uint8_t begin(uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use + virtual void stop(); // Finish with the UDP socket + + // Sending UDP packets + + // Start building up a packet to send to the remote host specific in ip and port + // Returns 1 if successful, 0 if there was a problem with the supplied IP address or port + virtual int beginPacket(IPAddress ip, uint16_t port); + // Start building up a packet to send to the remote host specific in host and port + // Returns 1 if successful, 0 if there was a problem resolving the hostname or port + virtual int beginPacket(const char *host, uint16_t port); + // Finish off this packet and send it + // Returns 1 if the packet was sent successfully, 0 if there was an error + virtual int endPacket(); + // Write a single byte into the packet + virtual size_t write(uint8_t); + // Write size bytes from buffer into the packet + virtual size_t write(const uint8_t *buffer, size_t size); + + // Send packet immediately from buffer + size_t writeImmediately(const uint8_t *buffer, size_t size); + + using Print::write; + + // Start processing the next available incoming packet + // Returns the size of the packet in bytes, or 0 if no packets are available + virtual int parsePacket(); + // Number of bytes remaining in the current packet + virtual int available(); + // Read a single byte from the current packet + virtual int read(); + // Read up to len bytes from the current packet and place them into buffer + // Returns the number of bytes read, or 0 if none are available + virtual int read(unsigned char* buffer, size_t len); + // Read up to len characters from the current packet and place them into buffer + // Returns the number of characters read, or 0 if none are available + virtual int read(char* buffer, size_t len) { return read((unsigned char*)buffer, len); }; + // Return the next byte from the current packet without moving on to the next byte + virtual int peek(); + virtual void flush(); // Finish reading the current packet + + // Return the IP address of the host who sent the current incoming packet + virtual IPAddress remoteIP(); + // Return the port of the host who sent the current incoming packet + virtual uint16_t remotePort(); + + friend class WiFiDrv; + + // extend API by RTK + + void setRecvTimeout(int timeout); +}; + +#endif diff --git a/builder/frameworks/realtek-ambz-arduino.py b/builder/frameworks/realtek-ambz-arduino.py index 1d43ec9..057e70d 100644 --- a/builder/frameworks/realtek-ambz-arduino.py +++ b/builder/frameworks/realtek-ambz-arduino.py @@ -163,6 +163,24 @@ sources_core += [ "+<" + FIXUPS_DIR + "/ssl_tls.c>", # rtl sdk defines S1 and S2 which conflicts here ] +# Arduino libraries +sources_libs = [ + # fmt: off + "+<" + CORE_DIR +"/libraries/WiFi/src/WiFi.cpp>" + "+<" + CORE_DIR +"/libraries/WiFi/src/WiFiClient.cpp>" + "+<" + CORE_DIR +"/libraries/WiFi/src/WiFiServer.cpp>" + "+<" + CORE_DIR +"/libraries/WiFi/src/WiFiSSLClient.cpp>" + "+<" + CORE_DIR +"/libraries/WiFi/src/WiFiUdp.cpp>" + # fmt: on +] +env.Append( + CPPPATH=[ + # fmt: off + join(CORE_DIR, "libraries", "WiFi", "src"), + # fmt: on + ], +) + # Libs & linker config env.Append( LIBS=[ @@ -180,9 +198,14 @@ env.Replace( envarduino = env.Clone() # Arduino Core library target -target_lib = envarduino.BuildLibrary( +target_core = envarduino.BuildLibrary( join("$BUILD_DIR", "ambz_arduino_core"), CORE_DIR, sources_core, ) -env.Prepend(LIBS=[target_lib]) +target_libs = envarduino.BuildLibrary( + join("$BUILD_DIR", "ambz_arduino_libs"), + CORE_DIR, + sources_libs, +) +env.Prepend(LIBS=[target_core, target_libs])