├── WiFiRM04Server.h ├── utility ├── wl_types.h ├── socket.c ├── server_drv.h ├── wl_definitions.h ├── debug.h ├── socket.h ├── spi_drv.h ├── server_drv.cpp ├── wifi_spi.h ├── wifi_drv.cpp ├── at_drv.h ├── QueueList.h ├── wifi_drv.h ├── spi_drv.cpp └── at_drv.cpp ├── WiFiRM04Client.h ├── keywords.txt ├── WiFiRM04Server.cpp ├── README.md ├── WiFiRM04Udp.h ├── examples ├── ScanNetworks │ └── ScanNetworks.ino ├── WiFiChatServer │ └── WiFiChatServer.ino ├── ConnectWithWPA │ └── ConnectWithWPA.ino ├── WiFiUdpSendReceiveString │ └── WiFiUdpSendReceiveString.ino ├── ConnectNoEncryption │ └── ConnectNoEncryption.ino ├── WiFiWebClient │ └── WiFiWebClient.ino ├── ConnectWithWEP │ └── ConnectWithWEP.ino ├── WiFiWebClientRepeating │ └── WiFiWebClientRepeating.ino ├── WiFiWebServer │ └── WiFiWebServer.ino ├── SimpleWebServerWiFi │ └── SimpleWebServerWiFi.ino ├── WiFiTwitterClient │ └── WiFiTwitterClient.ino ├── WiFiPachubeClientString │ └── WiFiPachubeClientString.ino ├── WiFiUdpNtpClient │ └── WiFiUdpNtpClient.ino └── WiFiPachubeClient │ └── WiFiPachubeClient.ino ├── WiFiRM04Udp.cpp ├── WiFiRM04Client.cpp ├── WiFiRM04.cpp └── WiFiRM04.h /WiFiRM04Server.h: -------------------------------------------------------------------------------- 1 | #ifndef WIFI_RM04_SERVER_H 2 | #define WIFI_RM04_SERVER_H 3 | 4 | extern "C" { 5 | #include "utility/wl_definitions.h" 6 | } 7 | 8 | #include "Server.h" 9 | 10 | class WiFiRM04Client; 11 | 12 | class WiFiRM04Server : public Server { 13 | private: 14 | uint16_t _port; 15 | void* pcb; 16 | public: 17 | WiFiRM04Server(uint16_t); 18 | WiFiRM04Client available(uint8_t* status = NULL); 19 | void begin(); 20 | virtual size_t write(uint8_t); 21 | virtual size_t write(const uint8_t *buf, size_t size); 22 | uint8_t status(); 23 | 24 | using Print::write; 25 | }; 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /utility/wl_types.h: -------------------------------------------------------------------------------- 1 | /* 2 | * wl_types.h 3 | * 4 | * Created on: Jul 30, 2010 5 | * Author: dlafauci 6 | */ 7 | 8 | 9 | #ifndef _WL_TYPES_H_ 10 | #define _WL_TYPES_H_ 11 | 12 | #include 13 | 14 | typedef enum { 15 | WL_FAILURE = -1, 16 | WL_SUCCESS = 1, 17 | } wl_error_code_t; 18 | 19 | /* Authentication modes */ 20 | enum wl_auth_mode { 21 | AUTH_MODE_INVALID, 22 | AUTH_MODE_AUTO, 23 | AUTH_MODE_OPEN_SYSTEM, 24 | AUTH_MODE_SHARED_KEY, 25 | AUTH_MODE_WPA, 26 | AUTH_MODE_WPA2, 27 | AUTH_MODE_WPA_PSK, 28 | AUTH_MODE_WPA2_PSK 29 | }; 30 | 31 | #endif //_WL_TYPES_H_ 32 | -------------------------------------------------------------------------------- /WiFiRM04Client.h: -------------------------------------------------------------------------------- 1 | #ifndef WIFI_RM04_CLIENT_H 2 | #define WIFI_RM04_CLIENT_H 3 | #include "Arduino.h" 4 | #include "Print.h" 5 | #include "Client.h" 6 | #include "IPAddress.h" 7 | 8 | class WiFiRM04Client : public Client { 9 | 10 | public: 11 | WiFiRM04Client(); 12 | WiFiRM04Client(uint8_t sock); 13 | 14 | uint8_t status(); 15 | virtual int connect(IPAddress ip, uint16_t port); 16 | virtual int connect(const char *host, uint16_t port); 17 | virtual size_t write(uint8_t); 18 | virtual size_t write(const uint8_t *buf, size_t size); 19 | virtual int available(); 20 | virtual int read(); 21 | virtual int read(uint8_t *buf, size_t size); 22 | virtual int peek(); 23 | virtual void flush(); 24 | virtual void stop(); 25 | virtual uint8_t connected(); 26 | virtual operator bool(); 27 | 28 | friend class WiFiRM04Server; 29 | 30 | using Print::write; 31 | 32 | private: 33 | static uint16_t _srcport; 34 | uint8_t _sock; //not used 35 | uint16_t _socket; 36 | 37 | uint8_t getFirstSocket(); 38 | }; 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /utility/socket.c: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | @file socket.c 4 | @brief define function of socket API 5 | * 6 | */ 7 | #include 8 | #include "socket.h" 9 | 10 | SOCKET socket(uint8 protocol) {return 0;} // Opens a socket(TCP or UDP or IP_RAW mode) 11 | void close(SOCKET s) {} // Close socket 12 | uint8 connect(SOCKET s, uint8 * addr, uint16 port) {return 0;} // Establish TCP connection (Active connection) 13 | void disconnect(SOCKET s) {} // disconnect the connection 14 | uint8 listen(SOCKET s) { return 0;} // Establish TCP connection (Passive connection) 15 | uint16 send(SOCKET s, const uint8 * buf, uint16 len) { return 0;} // Send data (TCP) 16 | uint16 recv(SOCKET s, uint8 * buf, uint16 len) {return 0;} // Receive data (TCP) 17 | uint16 sendto(SOCKET s, const uint8 * buf, uint16 len, uint8 * addr, uint16 port) {return 0;} // Send data (UDP/IP RAW) 18 | uint16 recvfrom(SOCKET s, uint8 * buf, uint16 len, uint8 * addr, uint16 *port) {return 0;} // Receive data (UDP/IP RAW) 19 | 20 | uint16 igmpsend(SOCKET s, const uint8 * buf, uint16 len) {return 0;} 21 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For WiFi 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | WiFi KEYWORD1 10 | WiFiRM04 KEYWORD1 11 | WiFiRM04Client KEYWORD1 12 | WiFiRM04Server KEYWORD1 13 | WiFiRM04UDP KEYWORD1 14 | 15 | ####################################### 16 | # Methods and Functions (KEYWORD2) 17 | ####################################### 18 | 19 | status KEYWORD2 20 | connect KEYWORD2 21 | write KEYWORD2 22 | available KEYWORD2 23 | config KEYWORD2 24 | setDNS KEYWORD2 25 | read KEYWORD2 26 | flush KEYWORD2 27 | stop KEYWORD2 28 | connected KEYWORD2 29 | begin KEYWORD2 30 | beginAsAp KEYWORD2 31 | disconnect KEYWORD2 32 | macAddress KEYWORD2 33 | localIP KEYWORD2 34 | subnetMask KEYWORD2 35 | gatewayIP KEYWORD2 36 | SSID KEYWORD2 37 | BSSID KEYWORD2 38 | RSSI KEYWORD2 39 | encryptionType KEYWORD2 40 | getResult KEYWORD2 41 | getSocket KEYWORD2 42 | WiFiRM04Client KEYWORD2 43 | WiFiRM04Server KEYWORD2 44 | WiFiRM04UDP KEYWORD2 45 | beginPacket KEYWORD2 46 | endPacket KEYWORD2 47 | parsePacket KEYWORD2 48 | remoteIP KEYWORD2 49 | remotePort KEYWORD2 50 | 51 | ####################################### 52 | # Constants (LITERAL1) 53 | ####################################### 54 | 55 | -------------------------------------------------------------------------------- /utility/server_drv.h: -------------------------------------------------------------------------------- 1 | #ifndef Server_Drv_h 2 | #define Server_Drv_h 3 | 4 | #include 5 | #include "wifi_spi.h" 6 | 7 | typedef enum eProtMode {TCP_MODE, UDP_MODE}tProtMode; 8 | 9 | class ServerDrv 10 | { 11 | public: 12 | 13 | // Start server TCP on port specified 14 | static void startServer(uint16_t port, uint8_t sock, uint8_t protMode=TCP_MODE); 15 | 16 | static void startClient(uint32_t ipAddress, uint16_t port, uint8_t sock, uint8_t protMode=TCP_MODE); 17 | 18 | static void startClient(const char *host, uint16_t port, uint8_t sock, uint8_t protMode=TCP_MODE); 19 | 20 | static void stopClient(uint8_t sock); 21 | 22 | static uint8_t getServerState(uint8_t sock); 23 | 24 | static uint8_t getClientState(uint8_t sock); 25 | 26 | static bool getData(uint8_t sock, uint8_t *data, uint8_t peek = 0); 27 | 28 | static bool getDataBuf(uint8_t sock, uint8_t *data, uint16_t *len); 29 | 30 | static bool insertDataBuf(uint8_t sock, const uint8_t *_data, uint16_t _dataLen); 31 | 32 | static bool sendData(uint8_t sock, const uint8_t *data, uint16_t len); 33 | 34 | static bool sendUdpData(uint8_t sock); 35 | 36 | static uint16_t availData(uint8_t sock); 37 | 38 | static uint8_t checkDataSent(uint8_t sock); 39 | }; 40 | 41 | extern ServerDrv serverDrv; 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /utility/wl_definitions.h: -------------------------------------------------------------------------------- 1 | /* 2 | * wl_definitions.h 3 | * 4 | * Created on: Mar 6, 2011 5 | * Author: dlafauci 6 | */ 7 | 8 | #ifndef WL_DEFINITIONS_H_ 9 | #define WL_DEFINITIONS_H_ 10 | 11 | // Maximum size of a SSID 12 | #define WL_SSID_MAX_LENGTH 32 13 | // Length of passphrase. Valid lengths are 8-63. 14 | #define WL_WPA_KEY_MAX_LENGTH 63 15 | // Length of key in bytes. Valid values are 5 and 13. 16 | #define WL_WEP_KEY_MAX_LENGTH 13 17 | // Size of a MAC-address or BSSID 18 | #define WL_MAC_ADDR_LENGTH 6 19 | // Size of a MAC-address or BSSID 20 | #define WL_IPV4_LENGTH 4 21 | // Maximum size of a SSID list 22 | #define WL_NETWORKS_LIST_MAXNUM 10 23 | // Maxmium number of socket 24 | #define MAX_SOCK_NUM 2 25 | // Default state value for Wifi state field 26 | #define NA_STATE -1 27 | //Maximum number of attempts to establish wifi connection 28 | #define WL_MAX_ATTEMPT_CONNECTION 10 29 | 30 | typedef enum { 31 | WL_NO_SHIELD = 255, 32 | WL_IDLE_STATUS = 0, 33 | WL_NO_SSID_AVAIL, 34 | WL_SCAN_COMPLETED, 35 | WL_CONNECTED, 36 | WL_CONNECT_FAILED, 37 | WL_CONNECTION_LOST, 38 | WL_DISCONNECTED 39 | } wl_status_t; 40 | 41 | /* Encryption modes */ 42 | enum wl_enc_type { /* Values map to 802.11 encryption suites... */ 43 | ENC_TYPE_WEP = 5, 44 | ENC_TYPE_TKIP = 2, 45 | ENC_TYPE_CCMP = 4, 46 | /* ... except these two, 7 and 8 are reserved in 802.11-2007 */ 47 | ENC_TYPE_NONE = 7, 48 | ENC_TYPE_AUTO = 8 49 | }; 50 | 51 | 52 | #endif /* WL_DEFINITIONS_H_ */ 53 | -------------------------------------------------------------------------------- /utility/debug.h: -------------------------------------------------------------------------------- 1 | //*********************************************/ 2 | // 3 | // File: debug.h 4 | // 5 | // Author: dlf (Metodo2 srl) 6 | // 7 | //********************************************/ 8 | 9 | 10 | #ifndef Debug_H 11 | #define Debug_H 12 | 13 | #include 14 | #include 15 | 16 | #define PRINT_FILE_LINE() do { \ 17 | Serial.print("[");Serial.print(__FILE__); \ 18 | Serial.print("::");Serial.print(__LINE__);Serial.print("]");\ 19 | }while (0); 20 | 21 | #ifdef _DEBUG_ 22 | 23 | #define INFO(format, args...) do { \ 24 | char buf[250]; \ 25 | sprintf(buf, format, args); \ 26 | Serial.println(buf); \ 27 | } while(0); 28 | 29 | #define INFO1(x) do { PRINT_FILE_LINE() Serial.print("-I-");\ 30 | Serial.println(x); \ 31 | }while (0); 32 | 33 | 34 | #define INFO2(x,y) do { PRINT_FILE_LINE() Serial.print("-I-");\ 35 | Serial.print(x,16);Serial.print(",");Serial.println(y,16); \ 36 | }while (0); 37 | 38 | 39 | #else 40 | #define INFO1(x) do {} while(0); 41 | #define INFO2(x,y) do {} while(0); 42 | #define INFO(format, args...) do {} while(0); 43 | #endif 44 | 45 | #if 0 46 | #define WARN(args) do { PRINT_FILE_LINE() \ 47 | Serial.print("-W-"); Serial.println(args); \ 48 | }while (0); 49 | #else 50 | #define WARN(args) do {} while (0); 51 | #endif 52 | 53 | #if _DEBUG_SPI_ 54 | #define DBG_PIN2 5 55 | #define DBG_PIN 4 56 | 57 | #define START() digitalWrite(DBG_PIN2, HIGH); 58 | #define END() digitalWrite(DBG_PIN2, LOW); 59 | #define SET_TRIGGER() digitalWrite(DBG_PIN, HIGH); 60 | #define RST_TRIGGER() digitalWrite(DBG_PIN, LOW); 61 | 62 | #define INIT_TRIGGER() pinMode(DBG_PIN, OUTPUT); \ 63 | pinMode(DBG_PIN2, OUTPUT); \ 64 | RST_TRIGGER() 65 | #define TOGGLE_TRIGGER() SET_TRIGGER() \ 66 | delayMicroseconds(2); \ 67 | RST_TRIGGER() 68 | #else 69 | #define START() 70 | #define END() 71 | #define SET_TRIGGER() 72 | #define RST_TRIGGER() 73 | #define INIT_TRIGGER() 74 | #define TOGGLE_TRIGGER() 75 | #endif 76 | 77 | #endif 78 | -------------------------------------------------------------------------------- /WiFiRM04Server.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "server_drv.h" 3 | 4 | extern "C" { 5 | #include "utility/debug.h" 6 | } 7 | 8 | #include "WiFiRM04.h" 9 | #include "WiFiRM04Client.h" 10 | #include "WiFiRM04Server.h" 11 | 12 | WiFiRM04Server::WiFiRM04Server(uint16_t port) 13 | { 14 | _port = port; 15 | } 16 | 17 | void WiFiRM04Server::begin() 18 | { 19 | uint8_t _sock = WiFiRM04Class::getSocket(); 20 | if (_sock != NO_SOCKET_AVAIL) 21 | { 22 | ServerDrv::startServer(_port, _sock); 23 | WiFiRM04Class::_server_port[_sock] = _port; 24 | WiFiRM04Class::_state[_sock] = _sock; 25 | } 26 | } 27 | 28 | WiFiRM04Client WiFiRM04Server::available(byte* status) 29 | { 30 | static int cycle_server_down = 0; 31 | const int TH_SERVER_DOWN = 50; 32 | 33 | for (int sock = 0; sock < MAX_SOCK_NUM; sock++) 34 | { 35 | if (WiFiRM04Class::_server_port[sock] == _port) 36 | { 37 | WiFiRM04Client client(sock); 38 | uint8_t _status = client.status(); 39 | uint8_t _ser_status = this->status(); 40 | 41 | if (status != NULL) 42 | *status = _status; 43 | 44 | //server not in listen state, restart it 45 | if ((_ser_status == 0)&&(cycle_server_down++ > TH_SERVER_DOWN)) 46 | { 47 | ServerDrv::startServer(_port, sock); 48 | cycle_server_down = 0; 49 | } 50 | 51 | if (_status == ESTABLISHED) 52 | { 53 | return client; //TODO 54 | } 55 | } 56 | } 57 | 58 | return WiFiRM04Client(255); 59 | } 60 | 61 | uint8_t WiFiRM04Server::status() { 62 | return ServerDrv::getServerState(0); 63 | } 64 | 65 | 66 | size_t WiFiRM04Server::write(uint8_t b) 67 | { 68 | return write(&b, 1); 69 | } 70 | 71 | size_t WiFiRM04Server::write(const uint8_t *buffer, size_t size) 72 | { 73 | size_t n = 0; 74 | 75 | for (int sock = 0; sock < MAX_SOCK_NUM; sock++) 76 | { 77 | if (WiFiRM04Class::_server_port[sock] != 0) 78 | { 79 | WiFiRM04Client client(sock); 80 | 81 | if (WiFiRM04Class::_server_port[sock] == _port && 82 | client.status() == ESTABLISHED) 83 | { 84 | n+=client.write(buffer, size); 85 | } 86 | } 87 | } 88 | return n; 89 | } 90 | -------------------------------------------------------------------------------- /utility/socket.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | @file socket.h 4 | @brief define function of socket API 5 | * 6 | */ 7 | 8 | #ifndef _SOCKET_H_ 9 | #define _SOCKET_H_ 10 | 11 | #define TCP_SOCKET 1 12 | #define UDP_SOCKET 2 13 | #define RAW_SOCKET 3 14 | 15 | #define SOCK_NOT_AVAIL 255 16 | 17 | #include "wl_definitions.h" 18 | /** 19 | * The 8-bit signed data type. 20 | */ 21 | typedef char int8; 22 | /** 23 | * The volatile 8-bit signed data type. 24 | */ 25 | typedef volatile char vint8; 26 | /** 27 | * The 8-bit unsigned data type. 28 | */ 29 | typedef unsigned char uint8; 30 | /** 31 | * The volatile 8-bit unsigned data type. 32 | */ 33 | typedef volatile unsigned char vuint8; 34 | 35 | /** 36 | * The 16-bit signed data type. 37 | */ 38 | typedef int int16; 39 | /** 40 | * The volatile 16-bit signed data type. 41 | */ 42 | typedef volatile int vint16; 43 | /** 44 | * The 16-bit unsigned data type. 45 | */ 46 | typedef unsigned int uint16; 47 | /** 48 | * The volatile 16-bit unsigned data type. 49 | */ 50 | typedef volatile unsigned int vuint16; 51 | /** 52 | * The 32-bit signed data type. 53 | */ 54 | typedef long int32; 55 | /** 56 | * The volatile 32-bit signed data type. 57 | */ 58 | typedef volatile long vint32; 59 | /** 60 | * The 32-bit unsigned data type. 61 | */ 62 | typedef unsigned long uint32; 63 | /** 64 | * The volatile 32-bit unsigned data type. 65 | */ 66 | typedef volatile unsigned long vuint32; 67 | 68 | /* bsd */ 69 | typedef uint8 u_char; /**< 8-bit value */ 70 | typedef uint16_t SOCKET; 71 | typedef uint16 u_short; /**< 16-bit value */ 72 | typedef uint16 u_int; /**< 16-bit value */ 73 | typedef uint32 u_long; /**< 32-bit value */ 74 | 75 | extern SOCKET socket(uint8 protocol); // Opens a socket(TCP or UDP or IP_RAW mode) 76 | extern void close(SOCKET s); // Close socket 77 | extern uint8 connect(SOCKET s, uint8 * addr, uint16 port); // Establish TCP connection (Active connection) 78 | extern void disconnect(SOCKET s); // disconnect the connection 79 | extern uint8 listen(SOCKET s); // Establish TCP connection (Passive connection) 80 | extern uint16 send(SOCKET s, const uint8 * buf, uint16 len); // Send data (TCP) 81 | extern uint16 recv(SOCKET s, uint8 * buf, uint16 len); // Receive data (TCP) 82 | extern uint16 sendto(SOCKET s, const uint8 * buf, uint16 len, uint8 * addr, uint16 port); // Send data (UDP/IP RAW) 83 | extern uint16 recvfrom(SOCKET s, uint8 * buf, uint16 len, uint8 * addr, uint16 *port); // Receive data (UDP/IP RAW) 84 | 85 | extern uint16 igmpsend(SOCKET s, const uint8 * buf, uint16 len); 86 | #endif 87 | /* _SOCKET_H_ */ 88 | -------------------------------------------------------------------------------- /utility/spi_drv.h: -------------------------------------------------------------------------------- 1 | #ifndef SPI_Drv_h 2 | #define SPI_Drv_h 3 | 4 | #include 5 | #include "wifi_spi.h" 6 | 7 | #define SPI_START_CMD_DELAY 10 8 | 9 | #define NO_LAST_PARAM 0 10 | #define LAST_PARAM 1 11 | 12 | #define DUMMY_DATA 0xFF 13 | 14 | #define WAIT_FOR_SLAVE_SELECT() \ 15 | SpiDrv::waitForSlaveReady(); \ 16 | SpiDrv::spiSlaveSelect(); 17 | 18 | 19 | 20 | class SpiDrv 21 | { 22 | private: 23 | //static bool waitSlaveReady(); 24 | static void waitForSlaveSign(); 25 | static void getParam(uint8_t* param); 26 | public: 27 | 28 | static void begin(); 29 | 30 | static void end(); 31 | 32 | static void spiDriverInit(); 33 | 34 | static void spiSlaveSelect(); 35 | 36 | static void spiSlaveDeselect(); 37 | 38 | static char spiTransfer(volatile char data); 39 | 40 | static void waitForSlaveReady(); 41 | 42 | //static int waitSpiChar(char waitChar, char* readChar); 43 | 44 | static int waitSpiChar(unsigned char waitChar); 45 | 46 | static int readAndCheckChar(char checkChar, char* readChar); 47 | 48 | static char readChar(); 49 | 50 | static int waitResponseParams(uint8_t cmd, uint8_t numParam, tParam* params); 51 | 52 | static int waitResponseCmd(uint8_t cmd, uint8_t numParam, uint8_t* param, uint8_t* param_len); 53 | 54 | static int waitResponseData8(uint8_t cmd, uint8_t* param, uint8_t* param_len); 55 | 56 | static int waitResponseData16(uint8_t cmd, uint8_t* param, uint16_t* param_len); 57 | /* 58 | static int waitResponse(uint8_t cmd, tParam* params, uint8_t* numParamRead, uint8_t maxNumParams); 59 | 60 | static int waitResponse(uint8_t cmd, uint8_t numParam, uint8_t* param, uint16_t* param_len); 61 | */ 62 | static int waitResponse(uint8_t cmd, uint8_t* numParamRead, uint8_t** params, uint8_t maxNumParams); 63 | 64 | static void sendParam(uint8_t* param, uint8_t param_len, uint8_t lastParam = NO_LAST_PARAM); 65 | 66 | static void sendParamLen8(uint8_t param_len); 67 | 68 | static void sendParamLen16(uint16_t param_len); 69 | 70 | static uint8_t readParamLen8(uint8_t* param_len = NULL); 71 | 72 | static uint16_t readParamLen16(uint16_t* param_len = NULL); 73 | 74 | static void sendBuffer(uint8_t* param, uint16_t param_len, uint8_t lastParam = NO_LAST_PARAM); 75 | 76 | static void sendParam(uint16_t param, uint8_t lastParam = NO_LAST_PARAM); 77 | 78 | static void sendCmd(uint8_t cmd, uint8_t numParam); 79 | }; 80 | 81 | extern SpiDrv spiDrv; 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WiFiRM04 Library 2 | WiFiRM04 library is an Arduino WiFi library for Hi-Link HLK-RM04 module. (http://www.hlktech.com/en/productshow.asp?id=142) 3 | This library is compatible with Arduino WiFi library and all examples of Arduino WiFi library could be compiled with this 4 | library with just a little modification. 5 | 6 | Currently, this library doesn't support UDP feature and assign a static IP in client mode. 7 | 8 | All features are tesed with firmware V1.78 and I have no idea if they could work with older firmware. 9 | 10 | ## How to Install 11 | 12 | 1. Download the WiFiRM04 library source. 13 | 1. In the Arduino IDE, go to the Sketch -> Import Library... -> Add Library... 14 | 1. Find the directory that contains the WiFiRM04 library source, and open it 15 | 1. Check if you could see "WiFiRM04" under Sketch -> Import Library... 16 | 17 | ## How to Use 18 | 19 | Since this library is compatible with Arduino WiFi library, you could check Arduino web site to learn how to use it. 20 | (http://arduino.cc/en/Reference/WiFi) 21 | 22 | ## Configuration 23 | 24 | First and most important, *MUST* modify Arduino's serial driver to increase Rx buffer size or add hardware flow control 25 | support, because HLK-RM04 will try to output all data at once. If Rx buffer of your serial port is too small(or no hardware 26 | flow control support), you will lose those data. 27 | 28 | By default, this library will use two UARTs to communicate with HLK-RM04 module. (firmware V1.78 can support two UARTs) 29 | If you don't want to use second UART of HLK-RM04, just modify utility/wl_definitions.h and change the definition 30 | of MAX_SOCK_NUM to 1. (but the second serial port will still be initialized in utilit/at_drv.cpp) 31 | 32 | The serial ports I used are Serial1 and Serial2, you could change them by modifying utilit/at_drv.cpp and change 33 | the definition of AT_DRV_SERIAL and AT_DRV_SERIAL1. 34 | 35 | Strongly suggest to use ES/RST pin to enter the AT command mode, but if you still want to change mode by 36 | sending specific serial data over serial port, just modify utilit/at_drv.cpp and mark #define USE_ESCAPE_PIN. 37 | 38 | Others like baud rate and the GPIO used to pull ES/RST pin could be found in the from of utilit/at_drv.cpp. 39 | You could understand their usage by checking the source and comments. 40 | 41 | ## Other Resources 42 | User manual of HLK-RM04 module. (http://www.hlktech.net/inc/lib/download/download.php?DId=19) 43 | 44 | This user manual doesn't contain the AT commands of lateset official firmware. (V1.78) 45 | You could find more useful information from the OpenWrt forum. (https://forum.openwrt.org/viewtopic.php?id=42142) 46 | -------------------------------------------------------------------------------- /WiFiRM04Udp.h: -------------------------------------------------------------------------------- 1 | #ifndef WIFI_RM04_UDP_H 2 | #define WIFI_RM04_UDP_H 3 | 4 | #include 5 | 6 | #define UDP_TX_PACKET_MAX_SIZE 24 7 | 8 | class WiFiRM04UDP : public UDP { 9 | private: 10 | uint8_t _sock; // socket ID for Wiz5100 11 | uint16_t _port; // local port to listen on 12 | 13 | public: 14 | WiFiRM04UDP(); // Constructor 15 | 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 16 | virtual void stop(); // Finish with the UDP socket 17 | 18 | // Sending UDP packets 19 | 20 | // Start building up a packet to send to the remote host specific in ip and port 21 | // Returns 1 if successful, 0 if there was a problem with the supplied IP address or port 22 | virtual int beginPacket(IPAddress ip, uint16_t port); 23 | // Start building up a packet to send to the remote host specific in host and port 24 | // Returns 1 if successful, 0 if there was a problem resolving the hostname or port 25 | virtual int beginPacket(const char *host, uint16_t port); 26 | // Finish off this packet and send it 27 | // Returns 1 if the packet was sent successfully, 0 if there was an error 28 | virtual int endPacket(); 29 | // Write a single byte into the packet 30 | virtual size_t write(uint8_t); 31 | // Write size bytes from buffer into the packet 32 | virtual size_t write(const uint8_t *buffer, size_t size); 33 | 34 | using Print::write; 35 | 36 | // Start processing the next available incoming packet 37 | // Returns the size of the packet in bytes, or 0 if no packets are available 38 | virtual int parsePacket(); 39 | // Number of bytes remaining in the current packet 40 | virtual int available(); 41 | // Read a single byte from the current packet 42 | virtual int read(); 43 | // Read up to len bytes from the current packet and place them into buffer 44 | // Returns the number of bytes read, or 0 if none are available 45 | virtual int read(unsigned char* buffer, size_t len); 46 | // Read up to len characters from the current packet and place them into buffer 47 | // Returns the number of characters read, or 0 if none are available 48 | virtual int read(char* buffer, size_t len) { return read((unsigned char*)buffer, len); }; 49 | // Return the next byte from the current packet without moving on to the next byte 50 | virtual int peek(); 51 | virtual void flush(); // Finish reading the current packet 52 | 53 | // Return the IP address of the host who sent the current incoming packet 54 | virtual IPAddress remoteIP(); 55 | // Return the port of the host who sent the current incoming packet 56 | virtual uint16_t remotePort(); 57 | 58 | friend class WiFiDrv; 59 | }; 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /utility/server_drv.cpp: -------------------------------------------------------------------------------- 1 | //#define _DEBUG_ 2 | 3 | #include "server_drv.h" 4 | 5 | #include "Arduino.h" 6 | #include "at_drv.h" 7 | 8 | extern "C" { 9 | #include "wl_types.h" 10 | #include "debug.h" 11 | } 12 | 13 | 14 | // Start server TCP on port specified 15 | void ServerDrv::startServer(uint16_t port, uint8_t sock, uint8_t protMode) 16 | { 17 | AtDrv::startServer(sock, port, protMode); 18 | } 19 | 20 | // Start server TCP on port specified 21 | void ServerDrv::startClient(uint32_t ipAddress, uint16_t port, uint8_t sock, uint8_t protMode) 22 | { 23 | AtDrv::startClient(sock, ipAddress, port, protMode); 24 | } 25 | 26 | // Start server TCP on port specified 27 | void ServerDrv::startClient(const char *host, uint16_t port, uint8_t sock, uint8_t protMode) 28 | { 29 | AtDrv::startClient(sock, host, port, protMode); 30 | } 31 | 32 | // Start server TCP on port specified 33 | void ServerDrv::stopClient(uint8_t sock) 34 | { 35 | AtDrv::stopClient(sock); 36 | } 37 | 38 | 39 | uint8_t ServerDrv::getServerState(uint8_t sock) 40 | { 41 | // Since RM04 can't get current connection status, we always return LISTEN 42 | return LISTEN; 43 | } 44 | 45 | uint8_t ServerDrv::getClientState(uint8_t sock) 46 | { 47 | return AtDrv::getClientState(sock); 48 | } 49 | 50 | uint16_t ServerDrv::availData(uint8_t sock) 51 | { 52 | return AtDrv::availData(sock); 53 | } 54 | 55 | bool ServerDrv::getData(uint8_t sock, uint8_t *data, uint8_t peek) 56 | { 57 | int ret; 58 | 59 | if(!data) 60 | return false; 61 | 62 | if(peek) 63 | ret = AtDrv::peek(sock); 64 | else 65 | ret = AtDrv::read(sock); 66 | 67 | *data = (uint8_t) ret; 68 | #ifdef _DEBUG_ 69 | if(ret >= 0) 70 | Serial.write(*data); 71 | #endif 72 | return (ret < 0)? false:true; 73 | } 74 | 75 | bool ServerDrv::getDataBuf(uint8_t sock, uint8_t *_data, uint16_t *_dataLen) 76 | { 77 | uint16_t ret; 78 | 79 | ret = AtDrv::readBytes(sock, _data, _dataLen); 80 | #ifdef _DEBUG_ 81 | if(ret) 82 | Serial.write(_data, *_dataLen); 83 | #endif 84 | return (ret)? true:false; 85 | } 86 | 87 | bool ServerDrv::insertDataBuf(uint8_t sock, const uint8_t *data, uint16_t _len) 88 | { 89 | // Not Support 90 | return false; 91 | } 92 | 93 | bool ServerDrv::sendUdpData(uint8_t sock) 94 | { 95 | // Not Support 96 | return false; 97 | } 98 | 99 | bool ServerDrv::sendData(uint8_t sock, const uint8_t *data, uint16_t len) 100 | { 101 | uint16_t ret; 102 | 103 | ret = AtDrv::write(sock, data, len); 104 | #ifdef _DEBUG_ 105 | Serial.write(data, len); 106 | #endif 107 | return (ret)? true:false; 108 | } 109 | 110 | 111 | uint8_t ServerDrv::checkDataSent(uint8_t sock) 112 | { 113 | return AtDrv::checkDataSent(sock); 114 | } 115 | 116 | ServerDrv serverDrv; 117 | -------------------------------------------------------------------------------- /examples/ScanNetworks/ScanNetworks.ino: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | This example prints the Wifi shield's MAC address, and 4 | scans for available Wifi networks using the Wifi shield. 5 | Every ten seconds, it scans again. It doesn't actually 6 | connect to any network, so no encryption scheme is specified. 7 | 8 | Circuit: 9 | * WiFi shield attached 10 | 11 | created 13 July 2010 12 | by dlf (Metodo2 srl) 13 | modified 21 Junn 2012 14 | by Tom Igoe and Jaymes Dec 15 | */ 16 | 17 | 18 | #include 19 | 20 | void setup() { 21 | //Initialize serial and wait for port to open: 22 | Serial.begin(9600); 23 | while (!Serial) { 24 | ; // wait for serial port to connect. Needed for Leonardo only 25 | } 26 | 27 | // check for the presence of the shield: 28 | if (WiFi.status() == WL_NO_SHIELD) { 29 | Serial.println("WiFi shield not present"); 30 | // don't continue: 31 | while(true); 32 | } 33 | 34 | // Print WiFi MAC address: 35 | printMacAddress(); 36 | 37 | // scan for existing networks: 38 | Serial.println("Scanning available networks..."); 39 | listNetworks(); 40 | } 41 | 42 | void loop() { 43 | delay(10000); 44 | // scan for existing networks: 45 | Serial.println("Scanning available networks..."); 46 | listNetworks(); 47 | } 48 | 49 | void printMacAddress() { 50 | // the MAC address of your Wifi shield 51 | byte mac[6]; 52 | 53 | // print your MAC address: 54 | WiFi.macAddress(mac); 55 | Serial.print("MAC: "); 56 | Serial.print(mac[5],HEX); 57 | Serial.print(":"); 58 | Serial.print(mac[4],HEX); 59 | Serial.print(":"); 60 | Serial.print(mac[3],HEX); 61 | Serial.print(":"); 62 | Serial.print(mac[2],HEX); 63 | Serial.print(":"); 64 | Serial.print(mac[1],HEX); 65 | Serial.print(":"); 66 | Serial.println(mac[0],HEX); 67 | } 68 | 69 | void listNetworks() { 70 | // scan for nearby networks: 71 | Serial.println("** Scan Networks **"); 72 | int numSsid = WiFi.scanNetworks(); 73 | if (numSsid == -1) 74 | { 75 | Serial.println("Couldn't get a wifi connection"); 76 | while(true); 77 | } 78 | 79 | // print the list of networks seen: 80 | Serial.print("number of available networks:"); 81 | Serial.println(numSsid); 82 | 83 | // print the network number and name for each network found: 84 | for (int thisNet = 0; thisNet 23 | 24 | char ssid[] = "yourNetwork"; // your network SSID (name) 25 | char pass[] = "secretPassword"; // your network password (use for WPA, or use as key for WEP) 26 | 27 | int keyIndex = 0; // your network key Index number (needed only for WEP) 28 | 29 | int status = WL_IDLE_STATUS; 30 | 31 | WiFiRM04Server server(23); 32 | 33 | boolean alreadyConnected = false; // whether or not the client was connected previously 34 | 35 | void setup() { 36 | //Initialize serial and wait for port to open: 37 | Serial.begin(9600); 38 | while (!Serial) { 39 | ; // wait for serial port to connect. Needed for Leonardo only 40 | } 41 | 42 | // check for the presence of the shield: 43 | if (WiFi.status() == WL_NO_SHIELD) { 44 | Serial.println("WiFi shield not present"); 45 | // don't continue: 46 | while(true); 47 | } 48 | 49 | // attempt to connect to Wifi network: 50 | while ( status != WL_CONNECTED) { 51 | Serial.print("Attempting to connect to SSID: "); 52 | Serial.println(ssid); 53 | // Connect to WPA/WPA2 network. Change this line if using open or WEP network: 54 | status = WiFi.begin(ssid, pass); 55 | 56 | // wait 10 seconds for connection: 57 | delay(10000); 58 | } 59 | // start the server: 60 | server.begin(); 61 | // you're connected now, so print out the status: 62 | printWifiStatus(); 63 | } 64 | 65 | 66 | void loop() { 67 | // wait for a new client: 68 | WiFiRM04Client client = server.available(); 69 | 70 | 71 | // when the client sends the first byte, say hello: 72 | if (client) { 73 | if (!alreadyConnected) { 74 | // clead out the input buffer: 75 | client.flush(); 76 | Serial.println("We have a new client"); 77 | client.println("Hello, client!"); 78 | alreadyConnected = true; 79 | } 80 | 81 | if (client.available() > 0) { 82 | // read the bytes incoming from the client: 83 | char thisChar = client.read(); 84 | // echo the bytes back to the client: 85 | server.write(thisChar); 86 | // echo the bytes to the server as well: 87 | Serial.write(thisChar); 88 | } 89 | } 90 | } 91 | 92 | 93 | void printWifiStatus() { 94 | // print the SSID of the network you're attached to: 95 | Serial.print("SSID: "); 96 | Serial.println(WiFi.SSID()); 97 | 98 | // print your WiFi shield's IP address: 99 | IPAddress ip = WiFi.localIP(); 100 | Serial.print("IP Address: "); 101 | Serial.println(ip); 102 | 103 | // print the received signal strength: 104 | long rssi = WiFi.RSSI(); 105 | Serial.print("signal strength (RSSI):"); 106 | Serial.print(rssi); 107 | Serial.println(" dBm"); 108 | } 109 | 110 | 111 | -------------------------------------------------------------------------------- /examples/ConnectWithWPA/ConnectWithWPA.ino: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | This example connects to an unencrypted Wifi network. 4 | Then it prints the MAC address of the Wifi shield, 5 | the IP address obtained, and other network details. 6 | 7 | Circuit: 8 | * WiFi shield attached 9 | 10 | created 13 July 2010 11 | by dlf (Metodo2 srl) 12 | modified 31 May 2012 13 | by Tom Igoe 14 | */ 15 | #include 16 | 17 | char ssid[] = "yourNetwork"; // your network SSID (name) 18 | char pass[] = "secretPassword"; // your network password 19 | int status = WL_IDLE_STATUS; // the Wifi radio's status 20 | 21 | void setup() { 22 | //Initialize serial and wait for port to open: 23 | Serial.begin(9600); 24 | while (!Serial) { 25 | ; // wait for serial port to connect. Needed for Leonardo only 26 | } 27 | 28 | // check for the presence of the shield: 29 | if (WiFi.status() == WL_NO_SHIELD) { 30 | Serial.println("WiFi shield not present"); 31 | // don't continue: 32 | while(true); 33 | } 34 | 35 | // attempt to connect to Wifi network: 36 | while ( status != WL_CONNECTED) { 37 | Serial.print("Attempting to connect to WPA SSID: "); 38 | Serial.println(ssid); 39 | // Connect to WPA/WPA2 network: 40 | status = WiFi.begin(ssid, pass); 41 | 42 | // wait 10 seconds for connection: 43 | delay(10000); 44 | } 45 | 46 | // you're connected now, so print out the data: 47 | Serial.print("You're connected to the network"); 48 | printCurrentNet(); 49 | printWifiData(); 50 | 51 | } 52 | 53 | void loop() { 54 | // check the network connection once every 10 seconds: 55 | delay(10000); 56 | printCurrentNet(); 57 | } 58 | 59 | void printWifiData() { 60 | // print your WiFi shield's IP address: 61 | IPAddress ip = WiFi.localIP(); 62 | Serial.print("IP Address: "); 63 | Serial.println(ip); 64 | Serial.println(ip); 65 | 66 | // print your MAC address: 67 | byte mac[6]; 68 | WiFi.macAddress(mac); 69 | Serial.print("MAC address: "); 70 | Serial.print(mac[5],HEX); 71 | Serial.print(":"); 72 | Serial.print(mac[4],HEX); 73 | Serial.print(":"); 74 | Serial.print(mac[3],HEX); 75 | Serial.print(":"); 76 | Serial.print(mac[2],HEX); 77 | Serial.print(":"); 78 | Serial.print(mac[1],HEX); 79 | Serial.print(":"); 80 | Serial.println(mac[0],HEX); 81 | 82 | } 83 | 84 | void printCurrentNet() { 85 | // print the SSID of the network you're attached to: 86 | Serial.print("SSID: "); 87 | Serial.println(WiFi.SSID()); 88 | 89 | // print the MAC address of the router you're attached to: 90 | byte bssid[6]; 91 | WiFi.BSSID(bssid); 92 | Serial.print("BSSID: "); 93 | Serial.print(bssid[5],HEX); 94 | Serial.print(":"); 95 | Serial.print(bssid[4],HEX); 96 | Serial.print(":"); 97 | Serial.print(bssid[3],HEX); 98 | Serial.print(":"); 99 | Serial.print(bssid[2],HEX); 100 | Serial.print(":"); 101 | Serial.print(bssid[1],HEX); 102 | Serial.print(":"); 103 | Serial.println(bssid[0],HEX); 104 | 105 | // print the received signal strength: 106 | long rssi = WiFi.RSSI(); 107 | Serial.print("signal strength (RSSI):"); 108 | Serial.println(rssi); 109 | 110 | // print the encryption type: 111 | byte encryption = WiFi.encryptionType(); 112 | Serial.print("Encryption Type:"); 113 | Serial.println(encryption,HEX); 114 | Serial.println(); 115 | } 116 | 117 | -------------------------------------------------------------------------------- /examples/WiFiUdpSendReceiveString/WiFiUdpSendReceiveString.ino: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | WiFi UDP Send and Receive String 4 | 5 | This sketch wait an UDP packet on localPort using a WiFi shield. 6 | When a packet is received an Acknowledge packet is sent to the client on port remotePort 7 | 8 | Circuit: 9 | * WiFi shield attached 10 | 11 | created 30 December 2012 12 | by dlf (Metodo2 srl) 13 | 14 | */ 15 | 16 | 17 | #include 18 | #include 19 | 20 | int status = WL_IDLE_STATUS; 21 | char ssid[] = "yourNetwork"; // your network SSID (name) 22 | char pass[] = "secretPassword"; // your network password (use for WPA, or use as key for WEP) 23 | int keyIndex = 0; // your network key Index number (needed only for WEP) 24 | 25 | unsigned int localPort = 2390; // local port to listen on 26 | 27 | char packetBuffer[255]; //buffer to hold incoming packet 28 | char ReplyBuffer[] = "acknowledged"; // a string to send back 29 | 30 | WiFiRM04UDP Udp; 31 | 32 | void setup() { 33 | //Initialize serial and wait for port to open: 34 | Serial.begin(9600); 35 | while (!Serial) { 36 | ; // wait for serial port to connect. Needed for Leonardo only 37 | } 38 | 39 | // check for the presence of the shield: 40 | if (WiFi.status() == WL_NO_SHIELD) { 41 | Serial.println("WiFi shield not present"); 42 | // don't continue: 43 | while(true); 44 | } 45 | 46 | // attempt to connect to Wifi network: 47 | while ( status != WL_CONNECTED) { 48 | Serial.print("Attempting to connect to SSID: "); 49 | Serial.println(ssid); 50 | // Connect to WPA/WPA2 network. Change this line if using open or WEP network: 51 | status = WiFi.begin(ssid); 52 | 53 | // wait 10 seconds for connection: 54 | delay(10000); 55 | } 56 | Serial.println("Connected to wifi"); 57 | printWifiStatus(); 58 | 59 | Serial.println("\nStarting connection to server..."); 60 | // if you get a connection, report back via serial: 61 | Udp.begin(localPort); 62 | } 63 | 64 | void loop() { 65 | 66 | // if there's data available, read a packet 67 | int packetSize = Udp.parsePacket(); 68 | if(packetSize) 69 | { 70 | Serial.print("Received packet of size "); 71 | Serial.println(packetSize); 72 | Serial.print("From "); 73 | IPAddress remoteIp = Udp.remoteIP(); 74 | Serial.print(remoteIp); 75 | Serial.print(", port "); 76 | Serial.println(Udp.remotePort()); 77 | 78 | // read the packet into packetBufffer 79 | int len = Udp.read(packetBuffer,255); 80 | if (len >0) packetBuffer[len]=0; 81 | Serial.println("Contents:"); 82 | Serial.println(packetBuffer); 83 | 84 | // send a reply, to the IP address and port that sent us the packet we received 85 | Udp.beginPacket(Udp.remoteIP(), Udp.remotePort()); 86 | Udp.write(ReplyBuffer); 87 | Udp.endPacket(); 88 | } 89 | } 90 | 91 | 92 | void printWifiStatus() { 93 | // print the SSID of the network you're attached to: 94 | Serial.print("SSID: "); 95 | Serial.println(WiFi.SSID()); 96 | 97 | // print your WiFi shield's IP address: 98 | IPAddress ip = WiFi.localIP(); 99 | Serial.print("IP Address: "); 100 | Serial.println(ip); 101 | 102 | // print the received signal strength: 103 | long rssi = WiFi.RSSI(); 104 | Serial.print("signal strength (RSSI):"); 105 | Serial.print(rssi); 106 | Serial.println(" dBm"); 107 | } 108 | 109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /examples/ConnectNoEncryption/ConnectNoEncryption.ino: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | This example connects to an unencrypted Wifi network. 4 | Then it prints the MAC address of the Wifi shield, 5 | the IP address obtained, and other network details. 6 | 7 | Circuit: 8 | * WiFi shield attached 9 | 10 | created 13 July 2010 11 | by dlf (Metodo2 srl) 12 | modified 31 May 2012 13 | by Tom Igoe 14 | */ 15 | #include 16 | 17 | char ssid[] = "yourNetwork"; // the name of your network 18 | int status = WL_IDLE_STATUS; // the Wifi radio's status 19 | 20 | void setup() { 21 | //Initialize serial and wait for port to open: 22 | Serial.begin(9600); 23 | while (!Serial) { 24 | ; // wait for serial port to connect. Needed for Leonardo only 25 | } 26 | 27 | // check for the presence of the shield: 28 | if (WiFi.status() == WL_NO_SHIELD) { 29 | Serial.println("WiFi shield not present"); 30 | // don't continue: 31 | while(true); 32 | } 33 | 34 | // attempt to connect to Wifi network: 35 | while ( status != WL_CONNECTED) { 36 | Serial.print("Attempting to connect to open SSID: "); 37 | Serial.println(ssid); 38 | status = WiFi.begin(ssid); 39 | 40 | // wait 10 seconds for connection: 41 | delay(10000); 42 | } 43 | 44 | // you're connected now, so print out the data: 45 | Serial.print("You're connected to the network"); 46 | printCurrentNet(); 47 | printWifiData(); 48 | } 49 | 50 | void loop() { 51 | // check the network connection once every 10 seconds: 52 | delay(10000); 53 | printCurrentNet(); 54 | } 55 | 56 | void printWifiData() { 57 | // print your WiFi shield's IP address: 58 | IPAddress ip = WiFi.localIP(); 59 | Serial.print("IP Address: "); 60 | Serial.println(ip); 61 | Serial.println(ip); 62 | 63 | // print your MAC address: 64 | byte mac[6]; 65 | WiFi.macAddress(mac); 66 | Serial.print("MAC address: "); 67 | Serial.print(mac[5],HEX); 68 | Serial.print(":"); 69 | Serial.print(mac[4],HEX); 70 | Serial.print(":"); 71 | Serial.print(mac[3],HEX); 72 | Serial.print(":"); 73 | Serial.print(mac[2],HEX); 74 | Serial.print(":"); 75 | Serial.print(mac[1],HEX); 76 | Serial.print(":"); 77 | Serial.println(mac[0],HEX); 78 | 79 | // print your subnet mask: 80 | IPAddress subnet = WiFi.subnetMask(); 81 | Serial.print("NetMask: "); 82 | Serial.println(subnet); 83 | 84 | // print your gateway address: 85 | IPAddress gateway = WiFi.gatewayIP(); 86 | Serial.print("Gateway: "); 87 | Serial.println(gateway); 88 | } 89 | 90 | void printCurrentNet() { 91 | // print the SSID of the network you're attached to: 92 | Serial.print("SSID: "); 93 | Serial.println(WiFi.SSID()); 94 | 95 | // print the MAC address of the router you're attached to: 96 | byte bssid[6]; 97 | WiFi.BSSID(bssid); 98 | Serial.print("BSSID: "); 99 | Serial.print(bssid[5],HEX); 100 | Serial.print(":"); 101 | Serial.print(bssid[4],HEX); 102 | Serial.print(":"); 103 | Serial.print(bssid[3],HEX); 104 | Serial.print(":"); 105 | Serial.print(bssid[2],HEX); 106 | Serial.print(":"); 107 | Serial.print(bssid[1],HEX); 108 | Serial.print(":"); 109 | Serial.println(bssid[0],HEX); 110 | 111 | // print the received signal strength: 112 | long rssi = WiFi.RSSI(); 113 | Serial.print("signal strength (RSSI):"); 114 | Serial.println(rssi); 115 | 116 | // print the encryption type: 117 | byte encryption = WiFi.encryptionType(); 118 | Serial.print("Encryption Type:"); 119 | Serial.println(encryption,HEX); 120 | } 121 | 122 | -------------------------------------------------------------------------------- /utility/wifi_spi.h: -------------------------------------------------------------------------------- 1 | #ifndef WiFi_Spi_h 2 | #define WiFi_Spi_h 3 | 4 | #include "wl_definitions.h" 5 | 6 | #define CMD_FLAG 0 7 | #define REPLY_FLAG 1<<7 8 | #define DATA_FLAG 0x40 9 | 10 | #define WIFI_SPI_ACK 1 11 | #define WIFI_SPI_ERR 0xFF 12 | 13 | #define TIMEOUT_CHAR 1000 14 | 15 | //#define MAX_SOCK_NUM 4 /**< Maxmium number of socket */ 16 | #define NO_SOCKET_AVAIL 255 17 | 18 | #define START_CMD 0xE0 19 | #define END_CMD 0xEE 20 | #define ERR_CMD 0xEF 21 | #define CMD_POS 1 // Position of Command OpCode on SPI stream 22 | #define PARAM_LEN_POS 2 // Position of Param len on SPI stream 23 | 24 | 25 | enum { 26 | SET_NET_CMD = 0x10, 27 | SET_PASSPHRASE_CMD = 0x11, 28 | SET_KEY_CMD = 0x12, 29 | TEST_CMD = 0x13, 30 | SET_IP_CONFIG_CMD = 0x14, 31 | SET_DNS_CONFIG_CMD = 0x15, 32 | 33 | GET_CONN_STATUS_CMD = 0x20, 34 | GET_IPADDR_CMD = 0x21, 35 | GET_MACADDR_CMD = 0x22, 36 | GET_CURR_SSID_CMD = 0x23, 37 | GET_CURR_BSSID_CMD = 0x24, 38 | GET_CURR_RSSI_CMD = 0x25, 39 | GET_CURR_ENCT_CMD = 0x26, 40 | SCAN_NETWORKS = 0x27, 41 | START_SERVER_TCP_CMD= 0x28, 42 | GET_STATE_TCP_CMD = 0x29, 43 | DATA_SENT_TCP_CMD = 0x2A, 44 | AVAIL_DATA_TCP_CMD = 0x2B, 45 | GET_DATA_TCP_CMD = 0x2C, 46 | START_CLIENT_TCP_CMD= 0x2D, 47 | STOP_CLIENT_TCP_CMD = 0x2E, 48 | GET_CLIENT_STATE_TCP_CMD= 0x2F, 49 | DISCONNECT_CMD = 0x30, 50 | GET_IDX_SSID_CMD = 0x31, 51 | GET_IDX_RSSI_CMD = 0x32, 52 | GET_IDX_ENCT_CMD = 0x33, 53 | REQ_HOST_BY_NAME_CMD= 0x34, 54 | GET_HOST_BY_NAME_CMD= 0x35, 55 | START_SCAN_NETWORKS = 0x36, 56 | GET_FW_VERSION_CMD = 0x37, 57 | GET_TEST_CMD = 0x38, 58 | SEND_DATA_UDP_CMD = 0x39, 59 | GET_REMOTE_DATA_CMD = 0x3A, 60 | 61 | // All command with DATA_FLAG 0x40 send a 16bit Len 62 | 63 | SEND_DATA_TCP_CMD = 0x44, 64 | GET_DATABUF_TCP_CMD = 0x45, 65 | INSERT_DATABUF_CMD = 0x46, 66 | }; 67 | 68 | 69 | enum wl_tcp_state { 70 | CLOSED = 0, 71 | LISTEN = 1, 72 | SYN_SENT = 2, 73 | SYN_RCVD = 3, 74 | ESTABLISHED = 4, 75 | FIN_WAIT_1 = 5, 76 | FIN_WAIT_2 = 6, 77 | CLOSE_WAIT = 7, 78 | CLOSING = 8, 79 | LAST_ACK = 9, 80 | TIME_WAIT = 10 81 | }; 82 | 83 | 84 | enum numParams{ 85 | PARAM_NUMS_0, 86 | PARAM_NUMS_1, 87 | PARAM_NUMS_2, 88 | PARAM_NUMS_3, 89 | PARAM_NUMS_4, 90 | PARAM_NUMS_5, 91 | MAX_PARAM_NUMS 92 | }; 93 | 94 | #define MAX_PARAMS MAX_PARAM_NUMS-1 95 | #define PARAM_LEN_SIZE 1 96 | 97 | typedef struct __attribute__((__packed__)) 98 | { 99 | uint8_t paramLen; 100 | char* param; 101 | }tParam; 102 | 103 | typedef struct __attribute__((__packed__)) 104 | { 105 | uint16_t dataLen; 106 | char* data; 107 | }tDataParam; 108 | 109 | 110 | typedef struct __attribute__((__packed__)) 111 | { 112 | unsigned char cmd; 113 | unsigned char tcmd; 114 | unsigned char nParam; 115 | tParam params[MAX_PARAMS]; 116 | }tSpiMsg; 117 | 118 | typedef struct __attribute__((__packed__)) 119 | { 120 | unsigned char cmd; 121 | unsigned char tcmd; 122 | unsigned char nParam; 123 | tDataParam params[MAX_PARAMS]; 124 | }tSpiMsgData; 125 | 126 | 127 | typedef struct __attribute__((__packed__)) 128 | { 129 | unsigned char cmd; 130 | unsigned char tcmd; 131 | //unsigned char totLen; 132 | unsigned char nParam; 133 | }tSpiHdr; 134 | 135 | typedef struct __attribute__((__packed__)) 136 | { 137 | uint8_t paramLen; 138 | uint32_t param; 139 | }tLongParam; 140 | 141 | typedef struct __attribute__((__packed__)) 142 | { 143 | uint8_t paramLen; 144 | uint16_t param; 145 | }tIntParam; 146 | 147 | typedef struct __attribute__((__packed__)) 148 | { 149 | uint8_t paramLen; 150 | uint8_t param; 151 | }tByteParam; 152 | 153 | #endif 154 | -------------------------------------------------------------------------------- /examples/WiFiWebClient/WiFiWebClient.ino: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | Web client 4 | 5 | This sketch connects to a website (http://www.google.com) 6 | using a WiFi shield. 7 | 8 | This example is written for a network using WPA encryption. For 9 | WEP or WPA, change the Wifi.begin() call accordingly. 10 | 11 | This example is written for a network using WPA encryption. For 12 | WEP or WPA, change the Wifi.begin() call accordingly. 13 | 14 | Circuit: 15 | * WiFi shield attached 16 | 17 | created 13 July 2010 18 | by dlf (Metodo2 srl) 19 | modified 31 May 2012 20 | by Tom Igoe 21 | */ 22 | 23 | 24 | #include 25 | 26 | char ssid[] = "yourNetwork"; // your network SSID (name) 27 | char pass[] = "secretPassword"; // your network password (use for WPA, or use as key for WEP) 28 | int keyIndex = 0; // your network key Index number (needed only for WEP) 29 | 30 | int status = WL_IDLE_STATUS; 31 | // if you don't want to use DNS (and reduce your sketch size) 32 | // use the numeric IP instead of the name for the server: 33 | //IPAddress server(74,125,232,128); // numeric IP for Google (no DNS) 34 | char server[] = "www.google.com"; // name address for Google (using DNS) 35 | 36 | // Initialize the Ethernet client library 37 | // with the IP address and port of the server 38 | // that you want to connect to (port 80 is default for HTTP): 39 | WiFiRM04Client client; 40 | 41 | void setup() { 42 | //Initialize serial and wait for port to open: 43 | Serial.begin(9600); 44 | while (!Serial) { 45 | ; // wait for serial port to connect. Needed for Leonardo only 46 | } 47 | 48 | // check for the presence of the shield: 49 | if (WiFi.status() == WL_NO_SHIELD) { 50 | Serial.println("WiFi shield not present"); 51 | // don't continue: 52 | while(true); 53 | } 54 | 55 | // attempt to connect to Wifi network: 56 | while (status != WL_CONNECTED) { 57 | Serial.print("Attempting to connect to SSID: "); 58 | Serial.println(ssid); 59 | // Connect to WPA/WPA2 network. Change this line if using open or WEP network: 60 | status = WiFi.begin(ssid, pass); 61 | 62 | // wait 10 seconds for connection: 63 | delay(10000); 64 | } 65 | Serial.println("Connected to wifi"); 66 | printWifiStatus(); 67 | 68 | Serial.println("\nStarting connection to server..."); 69 | // if you get a connection, report back via serial: 70 | if (client.connect(server, 80)) { 71 | Serial.println("connected to server"); 72 | // Make a HTTP request: 73 | client.println("GET /search?q=arduino HTTP/1.1"); 74 | client.println("Host: www.google.com"); 75 | client.println("Connection: close"); 76 | client.println(); 77 | } 78 | } 79 | 80 | void loop() { 81 | // if there are incoming bytes available 82 | // from the server, read them and print them: 83 | while (client.available()) { 84 | char c = client.read(); 85 | Serial.write(c); 86 | } 87 | 88 | // if the server's disconnected, stop the client: 89 | if (!client.connected()) { 90 | Serial.println(); 91 | Serial.println("disconnecting from server."); 92 | client.stop(); 93 | 94 | // do nothing forevermore: 95 | while(true); 96 | } 97 | } 98 | 99 | 100 | void printWifiStatus() { 101 | // print the SSID of the network you're attached to: 102 | Serial.print("SSID: "); 103 | Serial.println(WiFi.SSID()); 104 | 105 | // print your WiFi shield's IP address: 106 | IPAddress ip = WiFi.localIP(); 107 | Serial.print("IP Address: "); 108 | Serial.println(ip); 109 | 110 | // print the received signal strength: 111 | long rssi = WiFi.RSSI(); 112 | Serial.print("signal strength (RSSI):"); 113 | Serial.print(rssi); 114 | Serial.println(" dBm"); 115 | } 116 | 117 | 118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /WiFiRM04Udp.cpp: -------------------------------------------------------------------------------- 1 | 2 | extern "C" { 3 | #include "utility/debug.h" 4 | #include "utility/wifi_spi.h" 5 | } 6 | #include 7 | #include "server_drv.h" 8 | #include "wifi_drv.h" 9 | 10 | #include "WiFiRM04.h" 11 | #include "WiFiRM04Udp.h" 12 | #include "WiFiRM04Client.h" 13 | #include "WiFiRM04Server.h" 14 | 15 | 16 | /* Constructor */ 17 | WiFiRM04UDP::WiFiRM04UDP() : _sock(NO_SOCKET_AVAIL) {} 18 | 19 | /* Start WiFiRM04UDP socket, listening at local port PORT */ 20 | uint8_t WiFiRM04UDP::begin(uint16_t port) { 21 | 22 | uint8_t sock = WiFiRM04Class::getSocket(); 23 | if (sock != NO_SOCKET_AVAIL) 24 | { 25 | ServerDrv::startServer(port, sock, UDP_MODE); 26 | WiFiRM04Class::_server_port[sock] = port; 27 | _sock = sock; 28 | _port = port; 29 | return 1; 30 | } 31 | return 0; 32 | 33 | } 34 | 35 | /* return number of bytes available in the current packet, 36 | will return zero if parsePacket hasn't been called yet */ 37 | int WiFiRM04UDP::available() { 38 | if (_sock != NO_SOCKET_AVAIL) 39 | { 40 | return ServerDrv::availData(_sock); 41 | } 42 | return 0; 43 | } 44 | 45 | /* Release any resources being used by this WiFiRM04UDP instance */ 46 | void WiFiRM04UDP::stop() 47 | { 48 | if (_sock == NO_SOCKET_AVAIL) 49 | return; 50 | 51 | ServerDrv::stopClient(_sock); 52 | 53 | _sock = NO_SOCKET_AVAIL; 54 | } 55 | 56 | int WiFiRM04UDP::beginPacket(const char *host, uint16_t port) 57 | { 58 | // Look up the host first 59 | int ret = 0; 60 | IPAddress remote_addr; 61 | if (WiFi.hostByName(host, remote_addr)) 62 | { 63 | return beginPacket(remote_addr, port); 64 | } 65 | return ret; 66 | } 67 | 68 | int WiFiRM04UDP::beginPacket(IPAddress ip, uint16_t port) 69 | { 70 | if (_sock == NO_SOCKET_AVAIL) 71 | _sock = WiFiRM04Class::getSocket(); 72 | if (_sock != NO_SOCKET_AVAIL) 73 | { 74 | ServerDrv::startClient(uint32_t(ip), port, _sock, UDP_MODE); 75 | WiFiRM04Class::_state[_sock] = _sock; 76 | return 1; 77 | } 78 | return 0; 79 | } 80 | 81 | int WiFiRM04UDP::endPacket() 82 | { 83 | return ServerDrv::sendUdpData(_sock); 84 | } 85 | 86 | size_t WiFiRM04UDP::write(uint8_t byte) 87 | { 88 | return write(&byte, 1); 89 | } 90 | 91 | size_t WiFiRM04UDP::write(const uint8_t *buffer, size_t size) 92 | { 93 | ServerDrv::insertDataBuf(_sock, buffer, size); 94 | return size; 95 | } 96 | 97 | int WiFiRM04UDP::parsePacket() 98 | { 99 | return available(); 100 | } 101 | 102 | int WiFiRM04UDP::read() 103 | { 104 | uint8_t b; 105 | if (available()) 106 | { 107 | ServerDrv::getData(_sock, &b); 108 | return b; 109 | }else{ 110 | return -1; 111 | } 112 | } 113 | 114 | int WiFiRM04UDP::read(unsigned char* buffer, size_t len) 115 | { 116 | if (available()) 117 | { 118 | size_t size = 0; 119 | if (!ServerDrv::getDataBuf(_sock, buffer, &size)) 120 | return -1; 121 | // TODO check if the buffer is too smal respect to buffer size 122 | return size; 123 | }else{ 124 | return -1; 125 | } 126 | } 127 | 128 | int WiFiRM04UDP::peek() 129 | { 130 | uint8_t b; 131 | if (!available()) 132 | return -1; 133 | 134 | ServerDrv::getData(_sock, &b, 1); 135 | return b; 136 | } 137 | 138 | void WiFiRM04UDP::flush() 139 | { 140 | while (available()) 141 | read(); 142 | } 143 | 144 | IPAddress WiFiRM04UDP::remoteIP() 145 | { 146 | uint8_t _remoteIp[4] = {0}; 147 | uint8_t _remotePort[2] = {0}; 148 | 149 | WiFiDrv::getRemoteData(_sock, _remoteIp, _remotePort); 150 | IPAddress ip(_remoteIp); 151 | return ip; 152 | } 153 | 154 | uint16_t WiFiRM04UDP::remotePort() 155 | { 156 | uint8_t _remoteIp[4] = {0}; 157 | uint8_t _remotePort[2] = {0}; 158 | 159 | WiFiDrv::getRemoteData(_sock, _remoteIp, _remotePort); 160 | uint16_t port = (_remotePort[0]<<8)+_remotePort[1]; 161 | return port; 162 | } 163 | 164 | -------------------------------------------------------------------------------- /examples/ConnectWithWEP/ConnectWithWEP.ino: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | This example connects to a WEP-encrypted Wifi network. 4 | Then it prints the MAC address of the Wifi shield, 5 | the IP address obtained, and other network details. 6 | 7 | If you use 40-bit WEP, you need a key that is 10 characters long, 8 | and the characters must be hexadecimal (0-9 or A-F). 9 | e.g. for 40-bit, ABBADEAF01 will work, but ABBADEAF won't work 10 | (too short) and ABBAISDEAF won't work (I and S are not 11 | hexadecimal characters). 12 | 13 | For 128-bit, you need a string that is 26 characters long. 14 | D0D0DEADF00DABBADEAFBEADED will work because it's 26 characters, 15 | all in the 0-9, A-F range. 16 | 17 | Circuit: 18 | * WiFi shield attached 19 | 20 | created 13 July 2010 21 | by dlf (Metodo2 srl) 22 | modified 31 May 2012 23 | by Tom Igoe 24 | */ 25 | #include 26 | 27 | char ssid[] = "yourNetwork"; // your network SSID (name) 28 | char key[] = "D0D0DEADF00DABBADEAFBEADED"; // your network key 29 | int keyIndex = 0; // your network key Index number 30 | int status = WL_IDLE_STATUS; // the Wifi radio's status 31 | 32 | void setup() { 33 | //Initialize serial and wait for port to open: 34 | Serial.begin(9600); 35 | while (!Serial) { 36 | ; // wait for serial port to connect. Needed for Leonardo only 37 | } 38 | 39 | // check for the presence of the shield: 40 | if (WiFi.status() == WL_NO_SHIELD) { 41 | Serial.println("WiFi shield not present"); 42 | // don't continue: 43 | while(true); 44 | } 45 | 46 | // attempt to connect to Wifi network: 47 | while ( status != WL_CONNECTED) { 48 | Serial.print("Attempting to connect to WEP network, SSID: "); 49 | Serial.println(ssid); 50 | status = WiFi.begin(ssid, keyIndex, key); 51 | 52 | // wait 10 seconds for connection: 53 | delay(10000); 54 | } 55 | 56 | // once you are connected : 57 | Serial.print("You're connected to the network"); 58 | printCurrentNet(); 59 | printWifiData(); 60 | } 61 | 62 | void loop() { 63 | // check the network connection once every 10 seconds: 64 | delay(10000); 65 | printCurrentNet(); 66 | } 67 | 68 | void printWifiData() { 69 | // print your WiFi shield's IP address: 70 | IPAddress ip = WiFi.localIP(); 71 | Serial.print("IP Address: "); 72 | Serial.println(ip); 73 | Serial.println(ip); 74 | 75 | // print your MAC address: 76 | byte mac[6]; 77 | WiFi.macAddress(mac); 78 | Serial.print("MAC address: "); 79 | Serial.print(mac[5],HEX); 80 | Serial.print(":"); 81 | Serial.print(mac[4],HEX); 82 | Serial.print(":"); 83 | Serial.print(mac[3],HEX); 84 | Serial.print(":"); 85 | Serial.print(mac[2],HEX); 86 | Serial.print(":"); 87 | Serial.print(mac[1],HEX); 88 | Serial.print(":"); 89 | Serial.println(mac[0],HEX); 90 | } 91 | 92 | void printCurrentNet() { 93 | // print the SSID of the network you're attached to: 94 | Serial.print("SSID: "); 95 | Serial.println(WiFi.SSID()); 96 | 97 | // print the MAC address of the router you're attached to: 98 | byte bssid[6]; 99 | WiFi.BSSID(bssid); 100 | Serial.print("BSSID: "); 101 | Serial.print(bssid[5],HEX); 102 | Serial.print(":"); 103 | Serial.print(bssid[4],HEX); 104 | Serial.print(":"); 105 | Serial.print(bssid[3],HEX); 106 | Serial.print(":"); 107 | Serial.print(bssid[2],HEX); 108 | Serial.print(":"); 109 | Serial.print(bssid[1],HEX); 110 | Serial.print(":"); 111 | Serial.println(bssid[0],HEX); 112 | 113 | // print the received signal strength: 114 | long rssi = WiFi.RSSI(); 115 | Serial.print("signal strength (RSSI):"); 116 | Serial.println(rssi); 117 | 118 | // print the encryption type: 119 | byte encryption = WiFi.encryptionType(); 120 | Serial.print("Encryption Type:"); 121 | Serial.println(encryption,HEX); 122 | Serial.println(); 123 | } 124 | 125 | 126 | 127 | -------------------------------------------------------------------------------- /examples/WiFiWebClientRepeating/WiFiWebClientRepeating.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Repeating Wifi Web client 3 | 4 | This sketch connects to a a web server and makes a request 5 | using an Arduino Wifi shield. 6 | 7 | Circuit: 8 | * Wifi shield attached to pins 10, 11, 12, 13 9 | 10 | created 23 April 2012 11 | modifide 31 May 2012 12 | by Tom Igoe 13 | 14 | http://arduino.cc/en/Tutorial/WifiWebClientRepeating 15 | This code is in the public domain. 16 | */ 17 | 18 | #include 19 | 20 | char ssid[] = "yourNetwork"; // your network SSID (name) 21 | char pass[] = "secretPassword"; // your network password 22 | int keyIndex = 0; // your network key Index number (needed only for WEP) 23 | 24 | int status = WL_IDLE_STATUS; 25 | 26 | // Initialize the Wifi client library 27 | WiFiRM04Client client; 28 | 29 | // server address: 30 | char server[] = "www.arduino.cc"; 31 | //IPAddress server(64,131,82,241); 32 | 33 | unsigned long lastConnectionTime = 0; // last time you connected to the server, in milliseconds 34 | boolean lastConnected = false; // state of the connection last time through the main loop 35 | const unsigned long postingInterval = 10*1000; // delay between updates, in milliseconds 36 | 37 | void setup() { 38 | //Initialize serial and wait for port to open: 39 | Serial.begin(9600); 40 | while (!Serial) { 41 | ; // wait for serial port to connect. Needed for Leonardo only 42 | } 43 | 44 | // check for the presence of the shield: 45 | if (WiFi.status() == WL_NO_SHIELD) { 46 | Serial.println("WiFi shield not present"); 47 | // don't continue: 48 | while(true); 49 | } 50 | 51 | // attempt to connect to Wifi network: 52 | while ( status != WL_CONNECTED) { 53 | Serial.print("Attempting to connect to SSID: "); 54 | Serial.println(ssid); 55 | // Connect to WPA/WPA2 network. Change this line if using open or WEP network: 56 | status = WiFi.begin(ssid, pass); 57 | 58 | // wait 10 seconds for connection: 59 | delay(10000); 60 | } 61 | // you're connected now, so print out the status: 62 | printWifiStatus(); 63 | } 64 | 65 | void loop() { 66 | // if there's incoming data from the net connection. 67 | // send it out the serial port. This is for debugging 68 | // purposes only: 69 | while (client.available()) { 70 | char c = client.read(); 71 | Serial.write(c); 72 | } 73 | 74 | // if there's no net connection, but there was one last time 75 | // through the loop, then stop the client: 76 | if (!client.connected() && lastConnected) { 77 | Serial.println(); 78 | Serial.println("disconnecting."); 79 | client.stop(); 80 | } 81 | 82 | // if you're not connected, and ten seconds have passed since 83 | // your last connection, then connect again and send data: 84 | if(!client.connected() && (millis() - lastConnectionTime > postingInterval)) { 85 | httpRequest(); 86 | } 87 | // store the state of the connection for next time through 88 | // the loop: 89 | lastConnected = client.connected(); 90 | } 91 | 92 | // this method makes a HTTP connection to the server: 93 | void httpRequest() { 94 | // if there's a successful connection: 95 | if (client.connect(server, 80)) { 96 | Serial.println("connecting..."); 97 | // send the HTTP PUT request: 98 | client.println("GET /latest.txt HTTP/1.1"); 99 | client.println("Host: www.arduino.cc"); 100 | client.println("User-Agent: arduino-ethernet"); 101 | client.println("Connection: close"); 102 | client.println(); 103 | 104 | // note the time that the connection was made: 105 | lastConnectionTime = millis(); 106 | } 107 | else { 108 | // if you couldn't make a connection: 109 | Serial.println("connection failed"); 110 | Serial.println("disconnecting."); 111 | client.stop(); 112 | } 113 | } 114 | 115 | 116 | void printWifiStatus() { 117 | // print the SSID of the network you're attached to: 118 | Serial.print("SSID: "); 119 | Serial.println(WiFi.SSID()); 120 | 121 | // print your WiFi shield's IP address: 122 | IPAddress ip = WiFi.localIP(); 123 | Serial.print("IP Address: "); 124 | Serial.println(ip); 125 | 126 | // print the received signal strength: 127 | long rssi = WiFi.RSSI(); 128 | Serial.print("signal strength (RSSI):"); 129 | Serial.print(rssi); 130 | Serial.println(" dBm"); 131 | } 132 | 133 | 134 | 135 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /examples/WiFiWebServer/WiFiWebServer.ino: -------------------------------------------------------------------------------- 1 | /* 2 | WiFi Web Server 3 | 4 | A simple web server that shows the value of the analog input pins. 5 | using a WiFi shield. 6 | 7 | This example is written for a network using WPA encryption. For 8 | WEP or WPA, change the Wifi.begin() call accordingly. 9 | 10 | Circuit: 11 | * WiFi shield attached 12 | * Analog inputs attached to pins A0 through A5 (optional) 13 | 14 | created 13 July 2010 15 | by dlf (Metodo2 srl) 16 | modified 31 May 2012 17 | by Tom Igoe 18 | 19 | */ 20 | 21 | #include 22 | 23 | 24 | char ssid[] = "yourNetwork"; // your network SSID (name) 25 | char pass[] = "secretPassword"; // your network password 26 | int keyIndex = 0; // your network key Index number (needed only for WEP) 27 | 28 | int status = WL_IDLE_STATUS; 29 | 30 | WiFiRM04Server server(80); 31 | 32 | void setup() { 33 | //Initialize serial and wait for port to open: 34 | Serial.begin(9600); 35 | while (!Serial) { 36 | ; // wait for serial port to connect. Needed for Leonardo only 37 | } 38 | 39 | // check for the presence of the shield: 40 | if (WiFi.status() == WL_NO_SHIELD) { 41 | Serial.println("WiFi shield not present"); 42 | // don't continue: 43 | while(true); 44 | } 45 | 46 | // attempt to connect to Wifi network: 47 | while ( status != WL_CONNECTED) { 48 | Serial.print("Attempting to connect to SSID: "); 49 | Serial.println(ssid); 50 | // Connect to WPA/WPA2 network. Change this line if using open or WEP network: 51 | status = WiFi.begin(ssid, pass); 52 | 53 | // wait 10 seconds for connection: 54 | delay(10000); 55 | } 56 | server.begin(); 57 | // you're connected now, so print out the status: 58 | printWifiStatus(); 59 | } 60 | 61 | 62 | void loop() { 63 | // listen for incoming clients 64 | WiFiRM04Client client = server.available(); 65 | if (client) { 66 | Serial.println("new client"); 67 | // an http request ends with a blank line 68 | boolean currentLineIsBlank = true; 69 | while (client.connected()) { 70 | if (client.available()) { 71 | char c = client.read(); 72 | Serial.write(c); 73 | // if you've gotten to the end of the line (received a newline 74 | // character) and the line is blank, the http request has ended, 75 | // so you can send a reply 76 | if (c == '\n' && currentLineIsBlank) { 77 | // send a standard http response header 78 | client.println("HTTP/1.1 200 OK"); 79 | client.println("Content-Type: text/html"); 80 | client.println("Connection: close"); // the connection will be closed after completion of the response 81 | client.println("Refresh: 5"); // refresh the page automatically every 5 sec 82 | client.println(); 83 | client.println(""); 84 | client.println(""); 85 | // output the value of each analog input pin 86 | for (int analogChannel = 0; analogChannel < 6; analogChannel++) { 87 | int sensorReading = analogRead(analogChannel); 88 | client.print("analog input "); 89 | client.print(analogChannel); 90 | client.print(" is "); 91 | client.print(sensorReading); 92 | client.println("
"); 93 | } 94 | client.println(""); 95 | break; 96 | } 97 | if (c == '\n') { 98 | // you're starting a new line 99 | currentLineIsBlank = true; 100 | } 101 | else if (c != '\r') { 102 | // you've gotten a character on the current line 103 | currentLineIsBlank = false; 104 | } 105 | } 106 | } 107 | // give the web browser time to receive the data 108 | delay(1); 109 | 110 | // close the connection: 111 | client.stop(); 112 | Serial.println("client disonnected"); 113 | } 114 | } 115 | 116 | 117 | void printWifiStatus() { 118 | // print the SSID of the network you're attached to: 119 | Serial.print("SSID: "); 120 | Serial.println(WiFi.SSID()); 121 | 122 | // print your WiFi shield's IP address: 123 | IPAddress ip = WiFi.localIP(); 124 | Serial.print("IP Address: "); 125 | Serial.println(ip); 126 | 127 | // print the received signal strength: 128 | long rssi = WiFi.RSSI(); 129 | Serial.print("signal strength (RSSI):"); 130 | Serial.print(rssi); 131 | Serial.println(" dBm"); 132 | } 133 | 134 | -------------------------------------------------------------------------------- /WiFiRM04Client.cpp: -------------------------------------------------------------------------------- 1 | extern "C" { 2 | #include "utility/wl_definitions.h" 3 | #include "utility/wl_types.h" 4 | #include "socket.h" 5 | #include "string.h" 6 | #include "utility/debug.h" 7 | } 8 | 9 | #include "WiFiRM04.h" 10 | #include "WiFiRM04Client.h" 11 | #include "WiFiRM04Server.h" 12 | #include "server_drv.h" 13 | 14 | 15 | uint16_t WiFiRM04Client::_srcport = 1024; 16 | 17 | WiFiRM04Client::WiFiRM04Client() : _sock(MAX_SOCK_NUM) { 18 | } 19 | 20 | WiFiRM04Client::WiFiRM04Client(uint8_t sock) : _sock(sock) { 21 | if(sock >= MAX_SOCK_NUM) { 22 | _sock = 255; 23 | } 24 | } 25 | 26 | int WiFiRM04Client::connect(const char* host, uint16_t port) { 27 | if(_sock >= MAX_SOCK_NUM) 28 | _sock = getFirstSocket(); 29 | if (_sock != NO_SOCKET_AVAIL) 30 | { 31 | ServerDrv::startClient(host, port, _sock); 32 | WiFiRM04Class::_state[_sock] = _sock; 33 | 34 | unsigned long start = millis(); 35 | 36 | // wait 4 second for the connection to close 37 | while (!connected() && millis() - start < 10000) 38 | delay(1); 39 | 40 | if (!connected()) 41 | { 42 | return 0; 43 | } 44 | }else{ 45 | Serial.println("No Socket available"); 46 | return 0; 47 | } 48 | return 1; 49 | } 50 | 51 | int WiFiRM04Client::connect(IPAddress ip, uint16_t port) { 52 | if(_sock == MAX_SOCK_NUM) 53 | _sock = getFirstSocket(); 54 | if (_sock != NO_SOCKET_AVAIL) 55 | { 56 | ServerDrv::startClient(uint32_t(ip), port, _sock); 57 | WiFiRM04Class::_state[_sock] = _sock; 58 | 59 | unsigned long start = millis(); 60 | 61 | // wait 4 second for the connection to close 62 | while (!connected() && millis() - start < 10000) 63 | delay(1); 64 | 65 | if (!connected()) 66 | { 67 | return 0; 68 | } 69 | }else{ 70 | Serial.println("No Socket available"); 71 | return 0; 72 | } 73 | return 1; 74 | } 75 | 76 | size_t WiFiRM04Client::write(uint8_t b) { 77 | return write(&b, 1); 78 | } 79 | 80 | size_t WiFiRM04Client::write(const uint8_t *buf, size_t size) { 81 | if (_sock >= MAX_SOCK_NUM) 82 | { 83 | setWriteError(); 84 | return 0; 85 | } 86 | if (size==0) 87 | { 88 | setWriteError(); 89 | return 0; 90 | } 91 | 92 | 93 | if (!ServerDrv::sendData(_sock, buf, size)) 94 | { 95 | setWriteError(); 96 | return 0; 97 | } 98 | if (!ServerDrv::checkDataSent(_sock)) 99 | { 100 | setWriteError(); 101 | return 0; 102 | } 103 | 104 | return size; 105 | } 106 | 107 | int WiFiRM04Client::available() { 108 | if (_sock != 255) 109 | { 110 | return ServerDrv::availData(_sock); 111 | } 112 | 113 | return 0; 114 | } 115 | 116 | int WiFiRM04Client::read() { 117 | uint8_t b; 118 | if (!available()) 119 | return -1; 120 | 121 | ServerDrv::getData(_sock, &b); 122 | return b; 123 | } 124 | 125 | 126 | int WiFiRM04Client::read(uint8_t* buf, size_t size) { 127 | if (!ServerDrv::getDataBuf(_sock, buf, &size)) 128 | return -1; 129 | return 0; 130 | } 131 | 132 | int WiFiRM04Client::peek() { 133 | uint8_t b; 134 | if (!available()) 135 | return -1; 136 | 137 | ServerDrv::getData(_sock, &b, 1); 138 | return b; 139 | } 140 | 141 | void WiFiRM04Client::flush() { 142 | while (available()) 143 | read(); 144 | } 145 | 146 | void WiFiRM04Client::stop() { 147 | 148 | if (_sock == 255) 149 | return; 150 | 151 | ServerDrv::stopClient(_sock); 152 | WiFiRM04Class::_state[_sock] = NA_STATE; 153 | 154 | int count = 0; 155 | // wait maximum 5 secs for the connection to close 156 | // Don't wait since RM04 can't disconnect the connetion by itself 157 | //while (status() != CLOSED && ++count < 50) 158 | // delay(100); 159 | 160 | _sock = 255; 161 | } 162 | 163 | uint8_t WiFiRM04Client::connected() { 164 | 165 | if (_sock == 255) { 166 | return 0; 167 | } else { 168 | uint8_t s = status(); 169 | 170 | return !(s == LISTEN || s == CLOSED || s == FIN_WAIT_1 || 171 | s == FIN_WAIT_2 || s == TIME_WAIT || 172 | s == SYN_SENT || s== SYN_RCVD || 173 | (s == CLOSE_WAIT)); 174 | } 175 | } 176 | 177 | uint8_t WiFiRM04Client::status() { 178 | if (_sock == 255) { 179 | return CLOSED; 180 | } else { 181 | return ServerDrv::getClientState(_sock); 182 | } 183 | } 184 | 185 | WiFiRM04Client::operator bool() { 186 | return _sock != 255; 187 | } 188 | 189 | // Private Methods 190 | uint8_t WiFiRM04Client::getFirstSocket() 191 | { 192 | for (int i = 0; i < MAX_SOCK_NUM; i++) { 193 | if (WiFiRM04Class::_state[i] == NA_STATE) 194 | { 195 | return i; 196 | } 197 | } 198 | return SOCK_NOT_AVAIL; 199 | } 200 | 201 | -------------------------------------------------------------------------------- /examples/SimpleWebServerWiFi/SimpleWebServerWiFi.ino: -------------------------------------------------------------------------------- 1 | /* 2 | WiFi Web Server LED Blink 3 | 4 | A simple web server that lets you blink an LED via the web. 5 | This sketch will print the IP address of your WiFi Shield (once connected) 6 | to the Serial monitor. From there, you can open that address in a web browser 7 | to turn on and off the LED on pin 9. 8 | 9 | If the IP address of your shield is yourAddress: 10 | http://yourAddress/H turns the LED on 11 | http://yourAddress/L turns it off 12 | 13 | This example is written for a network using WPA encryption. For 14 | WEP or WPA, change the Wifi.begin() call accordingly. 15 | 16 | Circuit: 17 | * WiFi shield attached 18 | * LED attached to pin 9 19 | 20 | created 25 Nov 2012 21 | by Tom Igoe 22 | */ 23 | #include 24 | 25 | char ssid[] = "yourNetwork"; // your network SSID (name) 26 | char pass[] = "secretPassword"; // your network password 27 | int keyIndex = 0; // your network key Index number (needed only for WEP) 28 | 29 | int status = WL_IDLE_STATUS; 30 | WiFiRM04Server server(80); 31 | 32 | void setup() { 33 | Serial.begin(9600); // initialize serial communication 34 | pinMode(9, OUTPUT); // set the LED pin mode 35 | 36 | // check for the presence of the shield: 37 | if (WiFi.status() == WL_NO_SHIELD) { 38 | Serial.println("WiFi shield not present"); 39 | while(true); // don't continue 40 | } 41 | 42 | // attempt to connect to Wifi network: 43 | while ( status != WL_CONNECTED) { 44 | Serial.print("Attempting to connect to Network named: "); 45 | Serial.println(ssid); // print the network name (SSID); 46 | 47 | // Connect to WPA/WPA2 network. Change this line if using open or WEP network: 48 | status = WiFi.begin(ssid, pass); 49 | // wait 10 seconds for connection: 50 | delay(10000); 51 | } 52 | server.begin(); // start the web server on port 80 53 | printWifiStatus(); // you're connected now, so print out the status 54 | } 55 | 56 | 57 | void loop() { 58 | WiFiRM04Client client = server.available(); // listen for incoming clients 59 | 60 | if (client) { // if you get a client, 61 | Serial.println("new client"); // print a message out the serial port 62 | String currentLine = ""; // make a String to hold incoming data from the client 63 | while (client.connected()) { // loop while the client's connected 64 | if (client.available()) { // if there's bytes to read from the client, 65 | char c = client.read(); // read a byte, then 66 | Serial.write(c); // print it out the serial monitor 67 | if (c == '\n') { // if the byte is a newline character 68 | 69 | // if the current line is blank, you got two newline characters in a row. 70 | // that's the end of the client HTTP request, so send a response: 71 | if (currentLine.length() == 0) { 72 | // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK) 73 | // and a content-type so the client knows what's coming, then a blank line: 74 | client.println("HTTP/1.1 200 OK"); 75 | client.println("Content-type:text/html"); 76 | client.println(); 77 | 78 | // the content of the HTTP response follows the header: 79 | client.print("Click here turn the LED on pin 9 on
"); 80 | client.print("Click here turn the LED on pin 9 off
"); 81 | 82 | // The HTTP response ends with another blank line: 83 | client.println(); 84 | // break out of the while loop: 85 | break; 86 | } 87 | else { // if you got a newline, then clear currentLine: 88 | currentLine = ""; 89 | } 90 | } 91 | else if (c != '\r') { // if you got anything else but a carriage return character, 92 | currentLine += c; // add it to the end of the currentLine 93 | } 94 | 95 | // Check to see if the client request was "GET /H" or "GET /L": 96 | if (currentLine.endsWith("GET /H")) { 97 | digitalWrite(9, HIGH); // GET /H turns the LED on 98 | } 99 | if (currentLine.endsWith("GET /L")) { 100 | digitalWrite(9, LOW); // GET /L turns the LED off 101 | } 102 | } 103 | } 104 | // close the connection: 105 | client.stop(); 106 | Serial.println("client disonnected"); 107 | } 108 | } 109 | 110 | void printWifiStatus() { 111 | // print the SSID of the network you're attached to: 112 | Serial.print("SSID: "); 113 | Serial.println(WiFi.SSID()); 114 | 115 | // print your WiFi shield's IP address: 116 | IPAddress ip = WiFi.localIP(); 117 | Serial.print("IP Address: "); 118 | Serial.println(ip); 119 | 120 | // print the received signal strength: 121 | long rssi = WiFi.RSSI(); 122 | Serial.print("signal strength (RSSI):"); 123 | Serial.print(rssi); 124 | Serial.println(" dBm"); 125 | // print where to go in a browser: 126 | Serial.print("To see this page in action, open a browser to http://"); 127 | Serial.println(ip); 128 | } 129 | -------------------------------------------------------------------------------- /examples/WiFiTwitterClient/WiFiTwitterClient.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Wifi Twitter Client with Strings 3 | 4 | This sketch connects to Twitter using using an Arduino WiFi shield. 5 | It parses the XML returned, and looks for this is a tweet 6 | 7 | This example is written for a network using WPA encryption. For 8 | WEP or WPA, change the Wifi.begin() call accordingly. 9 | 10 | This example uses the String library, which is part of the Arduino core from 11 | version 0019. 12 | 13 | Circuit: 14 | * WiFi shield attached to pins 10, 11, 12, 13 15 | 16 | created 23 apr 2012 17 | modified 31 May 2012 18 | by Tom Igoe 19 | 20 | This code is in the public domain. 21 | 22 | */ 23 | #include 24 | 25 | char ssid[] = "yourNetwork"; // your network SSID (name) 26 | char pass[] = "password"; // your network password (use for WPA, or use as key for WEP) 27 | int keyIndex = 0; // your network key Index number (needed only for WEP) 28 | 29 | int status = WL_IDLE_STATUS; // status of the wifi connection 30 | 31 | // initialize the library instance: 32 | WiFiRM04Client client; 33 | 34 | const unsigned long requestInterval = 30*1000; // delay between requests; 30 seconds 35 | 36 | // if you don't want to use DNS (and reduce your sketch size) 37 | // use the numeric IP instead of the name for the server: 38 | //IPAddress server(199,59,149,200); // numeric IP for api.twitter.com 39 | char server[] = "api.twitter.com"; // name address for twitter API 40 | 41 | boolean requested; // whether you've made a request since connecting 42 | unsigned long lastAttemptTime = 0; // last time you connected to the server, in milliseconds 43 | 44 | String currentLine = ""; // string to hold the text from server 45 | String tweet = ""; // string to hold the tweet 46 | boolean readingTweet = false; // if you're currently reading the tweet 47 | 48 | void setup() { 49 | // reserve space for the strings: 50 | currentLine.reserve(256); 51 | tweet.reserve(150); 52 | //Initialize serial and wait for port to open: 53 | Serial.begin(9600); 54 | while (!Serial) { 55 | ; // wait for serial port to connect. Needed for Leonardo only 56 | } 57 | 58 | // check for the presence of the shield: 59 | if (WiFi.status() == WL_NO_SHIELD) { 60 | Serial.println("WiFi shield not present"); 61 | // don't continue: 62 | while(true); 63 | } 64 | 65 | // attempt to connect to Wifi network: 66 | while ( status != WL_CONNECTED) { 67 | Serial.print("Attempting to connect to SSID: "); 68 | Serial.println(ssid); 69 | // Connect to WPA/WPA2 network. Change this line if using open or WEP network: 70 | status = WiFi.begin(ssid, pass); 71 | 72 | // wait 10 seconds for connection: 73 | delay(10000); 74 | } 75 | // you're connected now, so print out the status: 76 | printWifiStatus(); 77 | connectToServer(); 78 | } 79 | 80 | void loop() 81 | { 82 | if (client.connected()) { 83 | if (client.available()) { 84 | // read incoming bytes: 85 | char inChar = client.read(); 86 | 87 | // add incoming byte to end of line: 88 | currentLine += inChar; 89 | 90 | // if you get a newline, clear the line: 91 | if (inChar == '\n') { 92 | currentLine = ""; 93 | } 94 | // if the current line ends with , it will 95 | // be followed by the tweet: 96 | if ( currentLine.endsWith("")) { 97 | // tweet is beginning. Clear the tweet string: 98 | readingTweet = true; 99 | tweet = ""; 100 | // break out of the loop so this character isn't added to the tweet: 101 | return; 102 | } 103 | // if you're currently reading the bytes of a tweet, 104 | // add them to the tweet String: 105 | if (readingTweet) { 106 | if (inChar != '<') { 107 | tweet += inChar; 108 | } 109 | else { 110 | // if you got a "<" character, 111 | // you've reached the end of the tweet: 112 | readingTweet = false; 113 | Serial.println(tweet); 114 | // close the connection to the server: 115 | client.stop(); 116 | } 117 | } 118 | } 119 | } 120 | else if (millis() - lastAttemptTime > requestInterval) { 121 | // if you're not connected, and two minutes have passed since 122 | // your last connection, then attempt to connect again: 123 | connectToServer(); 124 | } 125 | } 126 | 127 | void connectToServer() { 128 | // attempt to connect, and wait a millisecond: 129 | Serial.println("connecting to server..."); 130 | if (client.connect(server, 80)) { 131 | Serial.println("making HTTP request..."); 132 | // make HTTP GET request to twitter: 133 | client.println("GET /1/statuses/user_timeline.xml?screen_name=arduino HTTP/1.1"); 134 | client.println("Host: api.twitter.com"); 135 | client.println("Connection: close"); 136 | client.println(); 137 | } 138 | // note the time of this connect attempt: 139 | lastAttemptTime = millis(); 140 | } 141 | 142 | 143 | void printWifiStatus() { 144 | // print the SSID of the network you're attached to: 145 | Serial.print("SSID: "); 146 | Serial.println(WiFi.SSID()); 147 | 148 | // print your WiFi shield's IP address: 149 | IPAddress ip = WiFi.localIP(); 150 | Serial.print("IP Address: "); 151 | Serial.println(ip); 152 | 153 | // print the received signal strength: 154 | long rssi = WiFi.RSSI(); 155 | Serial.print("signal strength (RSSI):"); 156 | Serial.print(rssi); 157 | Serial.println(" dBm"); 158 | } 159 | 160 | 161 | 162 | 163 | -------------------------------------------------------------------------------- /utility/wifi_drv.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "Arduino.h" 6 | #include "at_drv.h" 7 | #include "wifi_drv.h" 8 | 9 | #define _DEBUG_ 10 | 11 | extern "C" { 12 | #include "wifi_spi.h" 13 | #include "wl_types.h" 14 | #include "debug.h" 15 | } 16 | 17 | // Array of data to cache the information related to the networks discovered 18 | char WiFiDrv::_networkSsid[][WL_SSID_MAX_LENGTH+1] = {{"1"},{"2"},{"3"},{"4"},{"5"}}; 19 | int32_t WiFiDrv::_networkRssi[WL_NETWORKS_LIST_MAXNUM] = { 0 }; 20 | uint8_t WiFiDrv::_networkEncr[WL_NETWORKS_LIST_MAXNUM] = { 0 }; 21 | uint8_t numList = 0; 22 | 23 | // Cached values of retrieved data 24 | char WiFiDrv::_ssid[] = {0}; 25 | uint8_t WiFiDrv::_bssid[] = {0}; 26 | uint8_t WiFiDrv::_mac[] = {0}; 27 | uint8_t WiFiDrv::_localIp[] = {0}; 28 | uint8_t WiFiDrv::_subnetMask[] = {0}; 29 | uint8_t WiFiDrv::_gatewayIp[] = {0}; 30 | // Firmware version 31 | char WiFiDrv::fwVersion[] = {0}; 32 | 33 | 34 | // Private Methods 35 | 36 | void WiFiDrv::getNetworkData(uint8_t *ip, uint8_t *mask, uint8_t *gwip) 37 | { 38 | AtDrv::getNetworkData(ip, mask, gwip); 39 | } 40 | 41 | void WiFiDrv::getRemoteData(uint8_t sock, uint8_t *ip, uint8_t *port) 42 | { 43 | AtDrv::getRemoteData(sock, ip, (uint16_t *)port); 44 | } 45 | 46 | 47 | // Public Methods 48 | 49 | 50 | void WiFiDrv::wifiDriverInit() 51 | { 52 | AtDrv::begin(); 53 | } 54 | 55 | bool WiFiDrv::wifiSetApMode(char* ssid, uint8_t ssid_len) 56 | { 57 | return AtDrv::setApSSID(ssid, 0, NULL); 58 | } 59 | 60 | int8_t WiFiDrv::wifiSetNetwork(char* ssid, uint8_t ssid_len) 61 | { 62 | bool ret; 63 | 64 | ret = AtDrv::setSSID(ssid, ENC_TYPE_NONE, NULL); 65 | 66 | return (ret)? WL_SUCCESS : WL_FAILURE; 67 | } 68 | 69 | int8_t WiFiDrv::wifiSetPassphrase(char* ssid, uint8_t ssid_len, const char *passphrase, const uint8_t len) 70 | { 71 | bool ret; 72 | 73 | ret = AtDrv::setSSID(ssid, ENC_TYPE_AUTO, passphrase); 74 | 75 | return (ret)? WL_SUCCESS : WL_FAILURE; 76 | } 77 | 78 | 79 | int8_t WiFiDrv::wifiSetKey(char* ssid, uint8_t ssid_len, uint8_t key_idx, const void *key, const uint8_t len) 80 | { 81 | bool ret; 82 | 83 | ret = AtDrv::setSSID(ssid, ENC_TYPE_WEP_OPEN, (char *)key); 84 | 85 | return (ret)? WL_SUCCESS : WL_FAILURE; 86 | } 87 | 88 | void WiFiDrv::config(uint8_t validParams, uint32_t local_ip, uint32_t gateway, uint32_t subnet) 89 | { 90 | // Not support 91 | } 92 | 93 | void WiFiDrv::setDNS(uint8_t validParams, uint32_t dns_server1, uint32_t dns_server2) 94 | { 95 | // Not support 96 | } 97 | 98 | 99 | 100 | int8_t WiFiDrv::disconnect() 101 | { 102 | bool ret; 103 | 104 | ret = AtDrv::disconnect(); 105 | 106 | return (ret)? WL_SUCCESS : WL_FAILURE; 107 | } 108 | 109 | uint8_t WiFiDrv::getConnectionStatus() 110 | { 111 | bool ret; 112 | 113 | ret = AtDrv::isWiFiConnected(); 114 | 115 | return (ret)? WL_CONNECTED : WL_IDLE_STATUS; 116 | } 117 | 118 | uint8_t* WiFiDrv::getMacAddress() 119 | { 120 | AtDrv::getMAC(_mac); 121 | return _mac; 122 | } 123 | 124 | void WiFiDrv::getIpAddress(IPAddress& ip) 125 | { 126 | getNetworkData(_localIp, _subnetMask, _gatewayIp); 127 | ip = _localIp; 128 | } 129 | 130 | void WiFiDrv::getSubnetMask(IPAddress& mask) 131 | { 132 | getNetworkData(_localIp, _subnetMask, _gatewayIp); 133 | mask = _subnetMask; 134 | } 135 | 136 | void WiFiDrv::getGatewayIP(IPAddress& ip) 137 | { 138 | getNetworkData(_localIp, _subnetMask, _gatewayIp); 139 | ip = _gatewayIp; 140 | } 141 | 142 | char* WiFiDrv::getCurrentSSID() 143 | { 144 | AtDrv::getCurrentSSID(_ssid); 145 | return _ssid; 146 | } 147 | 148 | uint8_t* WiFiDrv::getCurrentBSSID() 149 | { 150 | AtDrv::getCurrentBSSID(_bssid); 151 | return _bssid; 152 | } 153 | 154 | int32_t WiFiDrv::getCurrentRSSI() 155 | { 156 | return AtDrv::getCurrentRSSI(); 157 | } 158 | 159 | uint8_t WiFiDrv::getCurrentEncryptionType() 160 | { 161 | return AtDrv::getCurrentEncryptionType(); 162 | } 163 | 164 | int8_t WiFiDrv::startScanNetworks() 165 | { 166 | // do nothing, all things will be done at getSSIDNetoworks() 167 | return WL_SUCCESS; 168 | } 169 | 170 | 171 | uint8_t WiFiDrv::getScanNetworks() 172 | { 173 | numList = AtDrv::getScanNetworks(_networkSsid, _networkRssi, _networkEncr, WL_NETWORKS_LIST_MAXNUM); 174 | return numList; 175 | } 176 | 177 | char* WiFiDrv::getSSIDNetoworks(uint8_t networkItem) 178 | { 179 | if (networkItem >= WL_NETWORKS_LIST_MAXNUM || networkItem >= numList) 180 | return NULL; 181 | 182 | return _networkSsid[networkItem]; 183 | } 184 | 185 | uint8_t WiFiDrv::getEncTypeNetowrks(uint8_t networkItem) 186 | { 187 | if (networkItem >= WL_NETWORKS_LIST_MAXNUM || networkItem >= numList) 188 | return NULL; 189 | 190 | return _networkEncr[networkItem]; 191 | } 192 | 193 | int32_t WiFiDrv::getRSSINetoworks(uint8_t networkItem) 194 | { 195 | if (networkItem >= WL_NETWORKS_LIST_MAXNUM || networkItem >= numList) 196 | return NULL; 197 | 198 | return _networkRssi[networkItem]; 199 | } 200 | 201 | uint8_t WiFiDrv::reqHostByName(const char* aHostname) 202 | { 203 | // Not support 204 | return 0; 205 | } 206 | 207 | int WiFiDrv::getHostByName(IPAddress& aResult) 208 | { 209 | // Not support 210 | return 0; 211 | } 212 | 213 | int WiFiDrv::getHostByName(const char* aHostname, IPAddress& aResult) 214 | { 215 | // Not support 216 | return 0; 217 | } 218 | 219 | char* WiFiDrv::getFwVersion() 220 | { 221 | AtDrv::getFwVersion(fwVersion, WL_FW_VER_LENGTH); 222 | return fwVersion; 223 | } 224 | 225 | WiFiDrv wiFiDrv; 226 | -------------------------------------------------------------------------------- /utility/at_drv.h: -------------------------------------------------------------------------------- 1 | #ifndef AT_DRV_H 2 | #define AT_DRV_H 3 | 4 | #include "wifi_spi.h" 5 | #include 6 | 7 | #define SERIAL_TIMEOUT 50 8 | 9 | #define ENC_TYPE_NONE 0 10 | #define ENC_TYPE_WEP_OPEN 1 11 | #define ENC_TYPE_WEP 2 12 | #define ENC_TYPE_WPA_TKIP 3 13 | #define ENC_TYPE_WPA_AES 4 14 | #define ENC_TYPE_WPA2_AES 5 15 | #define ENC_TYPE_WPAWPA2_TKIP 6 16 | #define ENC_TYPE_WPAWPA2_AES 7 17 | #define ENC_TYPE_AUTO 8 18 | 19 | 20 | #define NET_MODE_DEFAULT 0 21 | #define NET_MODE_ETH 1 22 | #define NET_MODE_WIFI_CLIENT 2 23 | #define NET_MODE_WIFI_AP 3 24 | 25 | 26 | #define MODE_NONE 0 27 | #define MODE_CLIENT 1 28 | #define MODE_SERVER 2 29 | 30 | #define PROTO_MODE_TCP 0 31 | #define PROTO_MODE_UDP 1 32 | 33 | typedef enum LinuxTcpState { 34 | TCP_ESTABLISHED = 1, 35 | TCP_SYN_SENT, 36 | TCP_SYN_RECV, 37 | TCP_FIN_WAIT1, 38 | TCP_FIN_WAIT2, 39 | TCP_TIME_WAIT, 40 | TCP_CLOSE, 41 | TCP_CLOSE_WAIT, 42 | TCP_LAST_ACK, 43 | TCP_LISTEN, 44 | TCP_CLOSING, /* Now a valid state */ 45 | 46 | TCP_MAX_STATES /* Leave at the end! */ 47 | }; 48 | 49 | class AtDrv 50 | { 51 | private: 52 | static HardwareSerial* serialPort[2]; 53 | static bool atMode; 54 | static uint16_t sockPort[2]; 55 | static QueueList sock0DataQueue; 56 | static bool sockConnected[2]; 57 | static bool switchToAtMode(); 58 | static bool switchToDataMode(long timeout = SERIAL_TIMEOUT); 59 | static void setAtMode(bool mode); 60 | static bool echoTest(long timeout = SERIAL_TIMEOUT); 61 | static void clearSerialRxData(); 62 | static bool setWiFiConfig(char *ssid, int type, const char *password, long timeout = SERIAL_TIMEOUT); 63 | static bool getRemoteIp(uint8_t sock, uint8_t *ip, long timeout = SERIAL_TIMEOUT); 64 | static bool getLocalPort(uint8_t sock, uint16_t *port, long timeout = SERIAL_TIMEOUT); 65 | static bool getRemotePort(uint8_t sock, uint16_t *port, long timeout = SERIAL_TIMEOUT); 66 | static bool setNetMode(int netMode, long timeout = SERIAL_TIMEOUT); 67 | static void netCommit(); 68 | static bool reConnect(long timeout = SERIAL_TIMEOUT); 69 | static bool getMode(uint8_t sock, int *mode, long timeout = SERIAL_TIMEOUT); 70 | static bool setMode(uint8_t sock, int mode, long timeout = SERIAL_TIMEOUT); 71 | static bool getProtocol(uint8_t sock, uint8_t *protocol, long timeout = SERIAL_TIMEOUT); 72 | static bool setProtocol(uint8_t sock, uint8_t protocol, long timeout = SERIAL_TIMEOUT); 73 | static bool setLocalPort(uint8_t sock, uint16_t port, long timeout = SERIAL_TIMEOUT); 74 | static bool setPort(uint8_t sock, uint16_t port, long timeout = SERIAL_TIMEOUT); 75 | static bool setRemoteIp(uint8_t sock, uint32_t ip, long timeout = SERIAL_TIMEOUT); 76 | static bool getRemoteHost(uint8_t sock, char *host, long timeout = SERIAL_TIMEOUT); 77 | static bool setRemoteHost(uint8_t sock, const char *host, long timeout = SERIAL_TIMEOUT); 78 | static bool setDhcpd(bool enable, long timeout = SERIAL_TIMEOUT); 79 | static bool setDhcpdIp(uint32_t ipStart, uint32_t ipEnd, uint32_t mask, uint32_t gateway, long timeout = SERIAL_TIMEOUT); 80 | static bool setDhcpdDns(uint32_t dns1, uint32_t dns2, long timeout = SERIAL_TIMEOUT); 81 | static bool setDhcpdTime(uint32_t time, long timeout = SERIAL_TIMEOUT); 82 | static bool setNetIp(uint32_t ip, uint32_t mask, uint32_t gateway, long timeout= SERIAL_TIMEOUT); 83 | static bool setNetDns(uint32_t dns1, uint32_t dns2, long timeout = SERIAL_TIMEOUT); 84 | static bool getTcpAuto(uint8_t sock, bool *enable, long timeout = SERIAL_TIMEOUT); 85 | static bool setTcpAuto(uint8_t sock, bool enable, long timeout = SERIAL_TIMEOUT); 86 | static bool getNetworkTimeout(uint8_t sock, uint32_t *time, long timeout = SERIAL_TIMEOUT); 87 | static bool setNetworkTimeout(uint8_t sock, uint32_t time, long timeout = SERIAL_TIMEOUT); 88 | static uint8_t portStateMapping(LinuxTcpState linuxPortState); 89 | static void getLocalIp(uint8_t *ip, long timeout = SERIAL_TIMEOUT*5); 90 | static void getNetmask(uint8_t *mask, long timeout = SERIAL_TIMEOUT*5); 91 | static void getGateway(uint8_t *gwip, long timeout = SERIAL_TIMEOUT*5); 92 | 93 | public: 94 | AtDrv(); 95 | static bool isAtMode(); 96 | static void begin(); 97 | static void end(); 98 | static void getRemoteData(uint8_t sock, uint8_t *ip, uint16_t *port); 99 | static bool getMAC(uint8_t *mac, long timeout = SERIAL_TIMEOUT); 100 | static bool setApSSID(char *ssid, int type, const char *password); 101 | static bool setSSID(char *ssid, int type, const char *password = NULL); 102 | static void startServer(uint8_t sock, uint16_t port, uint8_t protMode); 103 | static void startClient(uint8_t sock, uint32_t ipAddress, uint16_t port, uint8_t protMode); 104 | static void startClient(uint8_t sock, const char *host, uint16_t port, uint8_t protMode); 105 | static uint16_t availData(uint8_t sock); 106 | static int peek(uint8_t sock); 107 | static int read(uint8_t sock); 108 | static uint16_t readBytes(uint8_t sock, uint8_t *_data, uint16_t *_dataLen); 109 | static uint16_t write(uint8_t sock, const uint8_t *data, uint16_t _len); 110 | static uint8_t getClientState(uint8_t sock, long timeout = SERIAL_TIMEOUT*5); 111 | static void stopClient(uint8_t sock); 112 | static bool isWiFiConnected(long timeout = SERIAL_TIMEOUT); 113 | static void getNetworkData(uint8_t *ip, uint8_t *mask, uint8_t *gwip); 114 | static bool disconnect(); 115 | static uint8_t getScanNetworks(char _networkSsid[][WL_SSID_MAX_LENGTH+1], int32_t _networkRssi[], uint8_t _networkEncr[], uint8_t maxItems, long timeout = SERIAL_TIMEOUT*20); 116 | static void getCurrentSSID(char _ssid[], long timeout = SERIAL_TIMEOUT*5); 117 | static void getCurrentBSSID(uint8_t _ssid[], long timeout = SERIAL_TIMEOUT*5); 118 | static int32_t getCurrentRSSI(long timeout = SERIAL_TIMEOUT*5); 119 | static uint8_t getCurrentEncryptionType(long timeout = SERIAL_TIMEOUT*5); 120 | static void getFwVersion(char fwVersion[], uint8_t bufLength, long timeout = SERIAL_TIMEOUT); 121 | static uint8_t checkDataSent(uint8_t sock); 122 | }; 123 | 124 | extern AtDrv atDrv; 125 | 126 | #endif 127 | -------------------------------------------------------------------------------- /examples/WiFiPachubeClientString/WiFiPachubeClientString.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Wifi Pachube sensor client with Strings 3 | 4 | This sketch connects an analog sensor to Pachube (http://www.pachube.com) 5 | using a Arduino Wifi shield. 6 | 7 | This example is written for a network using WPA encryption. For 8 | WEP or WPA, change the Wifi.begin() call accordingly. 9 | 10 | This example has been updated to use version 2.0 of the pachube.com API. 11 | To make it work, create a feed with a datastream, and give it the ID 12 | sensor1. Or change the code below to match your feed. 13 | 14 | This example uses the String library, which is part of the Arduino core from 15 | version 0019. 16 | 17 | Circuit: 18 | * Analog sensor attached to analog in 0 19 | * Wifi shield attached to pins 10, 11, 12, 13 20 | 21 | created 16 Mar 2012 22 | modified 31 May 2012 23 | by Tom Igoe 24 | modified 8 Sept 2012 25 | by Scott Fitzgerald 26 | 27 | This code is in the public domain. 28 | 29 | */ 30 | 31 | #include 32 | 33 | #define APIKEY "YOUR API KEY GOES HERE" // replace your pachube api key here 34 | #define FEEDID 00000 // replace your feed ID 35 | #define USERAGENT "My Arduino Project" // user agent is the project name 36 | 37 | char ssid[] = "yourNetwork"; // your network SSID (name) 38 | char pass[] = "secretPassword"; // your network password 39 | 40 | int status = WL_IDLE_STATUS; 41 | 42 | // initialize the library instance: 43 | WiFiRM04Client client; 44 | 45 | // if you don't want to use DNS (and reduce your sketch size) 46 | // use the numeric IP instead of the name for the server: 47 | //IPAddress server(216,52,233,121); // numeric IP for api.pachube.com 48 | char server[] = "api.pachube.com"; // name address for pachube API 49 | 50 | unsigned long lastConnectionTime = 0; // last time you connected to the server, in milliseconds 51 | boolean lastConnected = false; // state of the connection last time through the main loop 52 | const unsigned long postingInterval = 10*1000; //delay between updates to pachube.com 53 | 54 | void setup() { 55 | //Initialize serial and wait for port to open: 56 | Serial.begin(9600); 57 | while (!Serial) { 58 | ; // wait for serial port to connect. Needed for Leonardo only 59 | } 60 | 61 | // check for the presence of the shield: 62 | if (WiFi.status() == WL_NO_SHIELD) { 63 | Serial.println("WiFi shield not present"); 64 | // don't continue: 65 | while(true); 66 | } 67 | 68 | // attempt to connect to Wifi network: 69 | while ( status != WL_CONNECTED) { 70 | Serial.print("Attempting to connect to SSID: "); 71 | Serial.println(ssid); 72 | // Connect to WPA/WPA2 network. Change this line if using open or WEP network: 73 | status = WiFi.begin(ssid, pass); 74 | 75 | // wait 10 seconds for connection: 76 | delay(10000); 77 | } 78 | // you're connected now, so print out the status: 79 | printWifiStatus(); 80 | } 81 | 82 | void loop() { 83 | // read the analog sensor: 84 | int sensorReading = analogRead(A0); 85 | // convert the data to a String to send it: 86 | 87 | String dataString = "sensor1,"; 88 | dataString += sensorReading; 89 | 90 | // you can append multiple readings to this String if your 91 | // pachube feed is set up to handle multiple values: 92 | int otherSensorReading = analogRead(A1); 93 | dataString += "\nsensor2,"; 94 | dataString += otherSensorReading; 95 | 96 | // if there's incoming data from the net connection. 97 | // send it out the serial port. This is for debugging 98 | // purposes only: 99 | while (client.available()) { 100 | char c = client.read(); 101 | Serial.print(c); 102 | } 103 | 104 | // if there's no net connection, but there was one last time 105 | // through the loop, then stop the client: 106 | if (!client.connected() && lastConnected) { 107 | Serial.println(); 108 | Serial.println("disconnecting."); 109 | client.stop(); 110 | } 111 | 112 | // if you're not connected, and ten seconds have passed since 113 | // your last connection, then connect again and send data: 114 | if(!client.connected() && (millis() - lastConnectionTime > postingInterval)) { 115 | sendData(dataString); 116 | } 117 | // store the state of the connection for next time through 118 | // the loop: 119 | lastConnected = client.connected(); 120 | } 121 | 122 | // this method makes a HTTP connection to the server: 123 | void sendData(String thisData) { 124 | // if there's a successful connection: 125 | if (client.connect(server, 80)) { 126 | Serial.println("connecting..."); 127 | // send the HTTP PUT request: 128 | client.print("PUT /v2/feeds/"); 129 | client.print(FEEDID); 130 | client.println(".csv HTTP/1.1"); 131 | client.println("Host: api.pachube.com"); 132 | client.print("X-ApiKey: "); 133 | client.println(APIKEY); 134 | client.print("User-Agent: "); 135 | client.println(USERAGENT); 136 | client.print("Content-Length: "); 137 | client.println(thisData.length()); 138 | 139 | // last pieces of the HTTP PUT request: 140 | client.println("Content-Type: text/csv"); 141 | client.println("Connection: close"); 142 | client.println(); 143 | 144 | // here's the actual content of the PUT request: 145 | client.println(thisData); 146 | } 147 | else { 148 | // if you couldn't make a connection: 149 | Serial.println("connection failed"); 150 | Serial.println(); 151 | Serial.println("disconnecting."); 152 | client.stop(); 153 | } 154 | // note the time that the connection was made or attempted: 155 | lastConnectionTime = millis(); 156 | } 157 | 158 | 159 | void printWifiStatus() { 160 | // print the SSID of the network you're attached to: 161 | Serial.print("SSID: "); 162 | Serial.println(WiFi.SSID()); 163 | 164 | // print your WiFi shield's IP address: 165 | IPAddress ip = WiFi.localIP(); 166 | Serial.print("IP Address: "); 167 | Serial.println(ip); 168 | 169 | // print the received signal strength: 170 | long rssi = WiFi.RSSI(); 171 | Serial.print("signal strength (RSSI):"); 172 | Serial.print(rssi); 173 | Serial.println(" dBm"); 174 | } 175 | 176 | 177 | -------------------------------------------------------------------------------- /examples/WiFiUdpNtpClient/WiFiUdpNtpClient.ino: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Udp NTP Client 4 | 5 | Get the time from a Network Time Protocol (NTP) time server 6 | Demonstrates use of UDP sendPacket and ReceivePacket 7 | For more on NTP time servers and the messages needed to communicate with them, 8 | see http://en.wikipedia.org/wiki/Network_Time_Protocol 9 | 10 | created 4 Sep 2010 11 | by Michael Margolis 12 | modified 9 Apr 2012 13 | by Tom Igoe 14 | 15 | This code is in the public domain. 16 | 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | int status = WL_IDLE_STATUS; 23 | char ssid[] = "mynetwork"; // your network SSID (name) 24 | char pass[] = "mypassword"; // your network password 25 | int keyIndex = 0; // your network key Index number (needed only for WEP) 26 | 27 | unsigned int localPort = 2390; // local port to listen for UDP packets 28 | 29 | IPAddress timeServer(129, 6, 15, 28); // time.nist.gov NTP server 30 | 31 | const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message 32 | 33 | byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets 34 | 35 | // A UDP instance to let us send and receive packets over UDP 36 | WiFiRM04UDP Udp; 37 | 38 | void setup() 39 | { 40 | // Open serial communications and wait for port to open: 41 | Serial.begin(9600); 42 | while (!Serial) { 43 | ; // wait for serial port to connect. Needed for Leonardo only 44 | } 45 | 46 | // check for the presence of the shield: 47 | if (WiFi.status() == WL_NO_SHIELD) { 48 | Serial.println("WiFi shield not present"); 49 | // don't continue: 50 | while(true); 51 | } 52 | 53 | 54 | // attempt to connect to Wifi network: 55 | while ( status != WL_CONNECTED) { 56 | Serial.print("Attempting to connect to SSID: "); 57 | Serial.println(ssid); 58 | // Connect to WPA/WPA2 network. Change this line if using open or WEP network: 59 | status = WiFi.begin(ssid, pass); 60 | 61 | // wait 10 seconds for connection: 62 | delay(10000); 63 | } 64 | 65 | Serial.println("Connected to wifi"); 66 | printWifiStatus(); 67 | 68 | Serial.println("\nStarting connection to server..."); 69 | Udp.begin(localPort); 70 | } 71 | 72 | void loop() 73 | { 74 | sendNTPpacket(timeServer); // send an NTP packet to a time server 75 | // wait to see if a reply is available 76 | delay(1000); 77 | Serial.println( Udp.parsePacket() ); 78 | if ( Udp.parsePacket() ) { 79 | Serial.println("packet received"); 80 | // We've received a packet, read the data from it 81 | Udp.read(packetBuffer,NTP_PACKET_SIZE); // read the packet into the buffer 82 | 83 | //the timestamp starts at byte 40 of the received packet and is four bytes, 84 | // or two words, long. First, esxtract the two words: 85 | 86 | unsigned long highWord = word(packetBuffer[40], packetBuffer[41]); 87 | unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]); 88 | // combine the four bytes (two words) into a long integer 89 | // this is NTP time (seconds since Jan 1 1900): 90 | unsigned long secsSince1900 = highWord << 16 | lowWord; 91 | Serial.print("Seconds since Jan 1 1900 = " ); 92 | Serial.println(secsSince1900); 93 | 94 | // now convert NTP time into everyday time: 95 | Serial.print("Unix time = "); 96 | // Unix time starts on Jan 1 1970. In seconds, that's 2208988800: 97 | const unsigned long seventyYears = 2208988800UL; 98 | // subtract seventy years: 99 | unsigned long epoch = secsSince1900 - seventyYears; 100 | // print Unix time: 101 | Serial.println(epoch); 102 | 103 | 104 | // print the hour, minute and second: 105 | Serial.print("The UTC time is "); // UTC is the time at Greenwich Meridian (GMT) 106 | Serial.print((epoch % 86400L) / 3600); // print the hour (86400 equals secs per day) 107 | Serial.print(':'); 108 | if ( ((epoch % 3600) / 60) < 10 ) { 109 | // In the first 10 minutes of each hour, we'll want a leading '0' 110 | Serial.print('0'); 111 | } 112 | Serial.print((epoch % 3600) / 60); // print the minute (3600 equals secs per minute) 113 | Serial.print(':'); 114 | if ( (epoch % 60) < 10 ) { 115 | // In the first 10 seconds of each minute, we'll want a leading '0' 116 | Serial.print('0'); 117 | } 118 | Serial.println(epoch %60); // print the second 119 | } 120 | // wait ten seconds before asking for the time again 121 | delay(10000); 122 | } 123 | 124 | // send an NTP request to the time server at the given address 125 | unsigned long sendNTPpacket(IPAddress& address) 126 | { 127 | //Serial.println("1"); 128 | // set all bytes in the buffer to 0 129 | memset(packetBuffer, 0, NTP_PACKET_SIZE); 130 | // Initialize values needed to form NTP request 131 | // (see URL above for details on the packets) 132 | //Serial.println("2"); 133 | packetBuffer[0] = 0b11100011; // LI, Version, Mode 134 | packetBuffer[1] = 0; // Stratum, or type of clock 135 | packetBuffer[2] = 6; // Polling Interval 136 | packetBuffer[3] = 0xEC; // Peer Clock Precision 137 | // 8 bytes of zero for Root Delay & Root Dispersion 138 | packetBuffer[12] = 49; 139 | packetBuffer[13] = 0x4E; 140 | packetBuffer[14] = 49; 141 | packetBuffer[15] = 52; 142 | 143 | //Serial.println("3"); 144 | 145 | // all NTP fields have been given values, now 146 | // you can send a packet requesting a timestamp: 147 | Udp.beginPacket(address, 123); //NTP requests are to port 123 148 | //Serial.println("4"); 149 | Udp.write(packetBuffer,NTP_PACKET_SIZE); 150 | //Serial.println("5"); 151 | Udp.endPacket(); 152 | //Serial.println("6"); 153 | } 154 | 155 | 156 | void printWifiStatus() { 157 | // print the SSID of the network you're attached to: 158 | Serial.print("SSID: "); 159 | Serial.println(WiFi.SSID()); 160 | 161 | // print your WiFi shield's IP address: 162 | IPAddress ip = WiFi.localIP(); 163 | Serial.print("IP Address: "); 164 | Serial.println(ip); 165 | 166 | // print the received signal strength: 167 | long rssi = WiFi.RSSI(); 168 | Serial.print("signal strength (RSSI):"); 169 | Serial.print(rssi); 170 | Serial.println(" dBm"); 171 | } 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | -------------------------------------------------------------------------------- /WiFiRM04.cpp: -------------------------------------------------------------------------------- 1 | #include "wifi_drv.h" 2 | #include "WiFiRM04.h" 3 | 4 | extern "C" { 5 | #include "utility/wl_definitions.h" 6 | #include "utility/wl_types.h" 7 | #include "debug.h" 8 | } 9 | 10 | // XXX: don't make assumptions about the value of MAX_SOCK_NUM. 11 | #if MAX_SOCK_NUM == 1 12 | int16_t WiFiRM04Class::_state[MAX_SOCK_NUM] = { NA_STATE }; 13 | uint16_t WiFiRM04Class::_server_port[MAX_SOCK_NUM] = { 0 }; 14 | #else 15 | int16_t WiFiRM04Class::_state[MAX_SOCK_NUM] = { NA_STATE, NA_STATE }; 16 | uint16_t WiFiRM04Class::_server_port[MAX_SOCK_NUM] = { 0, 0 }; 17 | #endif 18 | 19 | WiFiRM04Class::WiFiRM04Class() 20 | { 21 | // Driver initialization 22 | init(); 23 | } 24 | 25 | void WiFiRM04Class::init() 26 | { 27 | WiFiDrv::wifiDriverInit(); 28 | } 29 | 30 | uint8_t WiFiRM04Class::getSocket() 31 | { 32 | for (uint8_t i = 0; i < MAX_SOCK_NUM; ++i) 33 | { 34 | if (WiFiRM04Class::_server_port[i] == 0) 35 | { 36 | return i; 37 | } 38 | } 39 | return NO_SOCKET_AVAIL; 40 | } 41 | 42 | char* WiFiRM04Class::firmwareVersion() 43 | { 44 | return WiFiDrv::getFwVersion(); 45 | } 46 | 47 | bool WiFiRM04Class::beginAsAp(char* ssid) 48 | { 49 | return WiFiDrv::wifiSetApMode(ssid, strlen(ssid)); 50 | } 51 | 52 | int WiFiRM04Class::begin(char* ssid) 53 | { 54 | uint8_t status = WL_IDLE_STATUS; 55 | uint8_t attempts = WL_MAX_ATTEMPT_CONNECTION; 56 | 57 | if (WiFiDrv::wifiSetNetwork(ssid, strlen(ssid)) != WL_FAILURE) 58 | { 59 | do 60 | { 61 | delay(WL_DELAY_START_CONNECTION); 62 | status = WiFiDrv::getConnectionStatus(); 63 | } 64 | while ((( status == WL_IDLE_STATUS)||(status == WL_SCAN_COMPLETED))&&(--attempts>0)); 65 | }else 66 | { 67 | status = WL_CONNECT_FAILED; 68 | } 69 | return status; 70 | } 71 | 72 | int WiFiRM04Class::begin(char* ssid, uint8_t key_idx, const char *key) 73 | { 74 | uint8_t status = WL_IDLE_STATUS; 75 | uint8_t attempts = WL_MAX_ATTEMPT_CONNECTION; 76 | 77 | // set encryption key 78 | if (WiFiDrv::wifiSetKey(ssid, strlen(ssid), key_idx, key, strlen(key)) != WL_FAILURE) 79 | { 80 | do 81 | { 82 | delay(WL_DELAY_START_CONNECTION); 83 | status = WiFiDrv::getConnectionStatus(); 84 | }while ((( status == WL_IDLE_STATUS)||(status == WL_SCAN_COMPLETED))&&(--attempts>0)); 85 | }else{ 86 | status = WL_CONNECT_FAILED; 87 | } 88 | return status; 89 | } 90 | 91 | int WiFiRM04Class::begin(char* ssid, const char *passphrase) 92 | { 93 | uint8_t status = WL_IDLE_STATUS; 94 | uint8_t attempts = WL_MAX_ATTEMPT_CONNECTION; 95 | 96 | // set passphrase 97 | if (WiFiDrv::wifiSetPassphrase(ssid, strlen(ssid), passphrase, strlen(passphrase))!= WL_FAILURE) 98 | { 99 | do 100 | { 101 | delay(WL_DELAY_START_CONNECTION); 102 | status = WiFiDrv::getConnectionStatus(); 103 | } 104 | while ((( status == WL_IDLE_STATUS)||(status == WL_SCAN_COMPLETED))&&(--attempts>0)); 105 | }else{ 106 | status = WL_CONNECT_FAILED; 107 | } 108 | return status; 109 | } 110 | 111 | void WiFiRM04Class::config(IPAddress local_ip) 112 | { 113 | WiFiDrv::config(1, (uint32_t)local_ip, 0, 0); 114 | } 115 | 116 | void WiFiRM04Class::config(IPAddress local_ip, IPAddress dns_server) 117 | { 118 | WiFiDrv::config(1, (uint32_t)local_ip, 0, 0); 119 | WiFiDrv::setDNS(1, (uint32_t)dns_server, 0); 120 | } 121 | 122 | void WiFiRM04Class::config(IPAddress local_ip, IPAddress dns_server, IPAddress gateway) 123 | { 124 | WiFiDrv::config(2, (uint32_t)local_ip, (uint32_t)gateway, 0); 125 | WiFiDrv::setDNS(1, (uint32_t)dns_server, 0); 126 | } 127 | 128 | void WiFiRM04Class::config(IPAddress local_ip, IPAddress dns_server, IPAddress gateway, IPAddress subnet) 129 | { 130 | WiFiDrv::config(3, (uint32_t)local_ip, (uint32_t)gateway, (uint32_t)subnet); 131 | WiFiDrv::setDNS(1, (uint32_t)dns_server, 0); 132 | } 133 | 134 | void WiFiRM04Class::setDNS(IPAddress dns_server1) 135 | { 136 | WiFiDrv::setDNS(1, (uint32_t)dns_server1, 0); 137 | } 138 | 139 | void WiFiRM04Class::setDNS(IPAddress dns_server1, IPAddress dns_server2) 140 | { 141 | WiFiDrv::setDNS(2, (uint32_t)dns_server1, (uint32_t)dns_server2); 142 | } 143 | 144 | int WiFiRM04Class::disconnect() 145 | { 146 | return WiFiDrv::disconnect(); 147 | } 148 | 149 | uint8_t* WiFiRM04Class::macAddress(uint8_t* mac) 150 | { 151 | uint8_t* _mac = WiFiDrv::getMacAddress(); 152 | memcpy(mac, _mac, WL_MAC_ADDR_LENGTH); 153 | return mac; 154 | } 155 | 156 | IPAddress WiFiRM04Class::localIP() 157 | { 158 | IPAddress ret; 159 | WiFiDrv::getIpAddress(ret); 160 | return ret; 161 | } 162 | 163 | IPAddress WiFiRM04Class::subnetMask() 164 | { 165 | IPAddress ret; 166 | WiFiDrv::getSubnetMask(ret); 167 | return ret; 168 | } 169 | 170 | IPAddress WiFiRM04Class::gatewayIP() 171 | { 172 | IPAddress ret; 173 | WiFiDrv::getGatewayIP(ret); 174 | return ret; 175 | } 176 | 177 | char* WiFiRM04Class::SSID() 178 | { 179 | return WiFiDrv::getCurrentSSID(); 180 | } 181 | 182 | uint8_t* WiFiRM04Class::BSSID(uint8_t* bssid) 183 | { 184 | uint8_t* _bssid = WiFiDrv::getCurrentBSSID(); 185 | memcpy(bssid, _bssid, WL_MAC_ADDR_LENGTH); 186 | return bssid; 187 | } 188 | 189 | int32_t WiFiRM04Class::RSSI() 190 | { 191 | return WiFiDrv::getCurrentRSSI(); 192 | } 193 | 194 | uint8_t WiFiRM04Class::encryptionType() 195 | { 196 | return WiFiDrv::getCurrentEncryptionType(); 197 | } 198 | 199 | 200 | int8_t WiFiRM04Class::scanNetworks() 201 | { 202 | uint8_t attempts = 10; 203 | uint8_t numOfNetworks = 0; 204 | 205 | if (WiFiDrv::startScanNetworks() == WL_FAILURE) 206 | return WL_FAILURE; 207 | do 208 | { 209 | delay(2000); 210 | numOfNetworks = WiFiDrv::getScanNetworks(); 211 | } 212 | while (( numOfNetworks == 0)&&(--attempts>0)); 213 | return numOfNetworks; 214 | } 215 | 216 | char* WiFiRM04Class::SSID(uint8_t networkItem) 217 | { 218 | return WiFiDrv::getSSIDNetoworks(networkItem); 219 | } 220 | 221 | int32_t WiFiRM04Class::RSSI(uint8_t networkItem) 222 | { 223 | return WiFiDrv::getRSSINetoworks(networkItem); 224 | } 225 | 226 | uint8_t WiFiRM04Class::encryptionType(uint8_t networkItem) 227 | { 228 | return WiFiDrv::getEncTypeNetowrks(networkItem); 229 | } 230 | 231 | uint8_t WiFiRM04Class::status() 232 | { 233 | return WiFiDrv::getConnectionStatus(); 234 | } 235 | 236 | int WiFiRM04Class::hostByName(const char* aHostname, IPAddress& aResult) 237 | { 238 | return WiFiDrv::getHostByName(aHostname, aResult); 239 | } 240 | 241 | WiFiRM04Class WiFi; 242 | -------------------------------------------------------------------------------- /examples/WiFiPachubeClient/WiFiPachubeClient.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Wifi Pachube sensor client 3 | 4 | This sketch connects an analog sensor to Pachube (http://www.pachube.com) 5 | using an Arduino Wifi shield. 6 | 7 | This example is written for a network using WPA encryption. For 8 | WEP or WPA, change the Wifi.begin() call accordingly. 9 | 10 | This example has been updated to use version 2.0 of the Pachube API. 11 | To make it work, create a feed with a datastream, and give it the ID 12 | sensor1. Or change the code below to match your feed. 13 | 14 | Circuit: 15 | * Analog sensor attached to analog in 0 16 | * Wifi shield attached to pins 10, 11, 12, 13 17 | 18 | created 13 Mar 2012 19 | modified 31 May 2012 20 | by Tom Igoe 21 | modified 8 Sept 2012 22 | by Scott Fitzgerald 23 | 24 | This code is in the public domain. 25 | 26 | */ 27 | #include 28 | 29 | #define APIKEY "YOUR API KEY GOES HERE" // replace your pachube api key here 30 | #define FEEDID 00000 // replace your feed ID 31 | #define USERAGENT "My Arduino Project" // user agent is the project name 32 | 33 | char ssid[] = "yourNetwork"; // your network SSID (name) 34 | char pass[] = "secretPassword"; // your network password 35 | 36 | int status = WL_IDLE_STATUS; 37 | 38 | // initialize the library instance: 39 | WiFiRM04Client client; 40 | // if you don't want to use DNS (and reduce your sketch size) 41 | // use the numeric IP instead of the name for the server: 42 | IPAddress server(216,52,233,121); // numeric IP for api.pachube.com 43 | //char server[] = "api.pachube.com"; // name address for pachube API 44 | 45 | unsigned long lastConnectionTime = 0; // last time you connected to the server, in milliseconds 46 | boolean lastConnected = false; // state of the connection last time through the main loop 47 | const unsigned long postingInterval = 10*1000; //delay between updates to pachube.com 48 | 49 | void setup() { 50 | //Initialize serial and wait for port to open: 51 | Serial.begin(9600); 52 | while (!Serial) { 53 | ; // wait for serial port to connect. Needed for Leonardo only 54 | } 55 | 56 | // check for the presence of the shield: 57 | if (WiFi.status() == WL_NO_SHIELD) { 58 | Serial.println("WiFi shield not present"); 59 | // don't continue: 60 | while(true); 61 | } 62 | 63 | // attempt to connect to Wifi network: 64 | while ( status != WL_CONNECTED) { 65 | Serial.print("Attempting to connect to SSID: "); 66 | Serial.println(ssid); 67 | // Connect to WPA/WPA2 network. Change this line if using open or WEP network: 68 | status = WiFi.begin(ssid, pass); 69 | 70 | // wait 10 seconds for connection: 71 | delay(10000); 72 | } 73 | // you're connected now, so print out the status: 74 | printWifiStatus(); 75 | } 76 | 77 | 78 | void loop() { 79 | // read the analog sensor: 80 | int sensorReading = analogRead(A0); 81 | 82 | // if there's incoming data from the net connection. 83 | // send it out the serial port. This is for debugging 84 | // purposes only: 85 | while (client.available()) { 86 | char c = client.read(); 87 | Serial.print(c); 88 | } 89 | 90 | // if there's no net connection, but there was one last time 91 | // through the loop, then stop the client: 92 | if (!client.connected() && lastConnected) { 93 | Serial.println(); 94 | Serial.println("disconnecting."); 95 | client.stop(); 96 | } 97 | 98 | // if you're not connected, and ten seconds have passed since 99 | // your last connection, then connect again and send data: 100 | if(!client.connected() && (millis() - lastConnectionTime > postingInterval)) { 101 | sendData(sensorReading); 102 | } 103 | // store the state of the connection for next time through 104 | // the loop: 105 | lastConnected = client.connected(); 106 | } 107 | 108 | // this method makes a HTTP connection to the server: 109 | void sendData(int thisData) { 110 | // if there's a successful connection: 111 | if (client.connect(server, 80)) { 112 | Serial.println("connecting..."); 113 | // send the HTTP PUT request: 114 | client.print("PUT /v2/feeds/"); 115 | client.print(FEEDID); 116 | client.println(".csv HTTP/1.1"); 117 | client.println("Host: api.pachube.com"); 118 | client.print("X-ApiKey: "); 119 | client.println(APIKEY); 120 | client.print("User-Agent: "); 121 | client.println(USERAGENT); 122 | client.print("Content-Length: "); 123 | 124 | // calculate the length of the sensor reading in bytes: 125 | // 8 bytes for "sensor1," + number of digits of the data: 126 | int thisLength = 8 + getLength(thisData); 127 | client.println(thisLength); 128 | 129 | // last pieces of the HTTP PUT request: 130 | client.println("Content-Type: text/csv"); 131 | client.println("Connection: close"); 132 | client.println(); 133 | 134 | // here's the actual content of the PUT request: 135 | client.print("sensor1,"); 136 | client.println(thisData); 137 | 138 | } 139 | else { 140 | // if you couldn't make a connection: 141 | Serial.println("connection failed"); 142 | Serial.println(); 143 | Serial.println("disconnecting."); 144 | client.stop(); 145 | } 146 | // note the time that the connection was made or attempted: 147 | lastConnectionTime = millis(); 148 | } 149 | 150 | 151 | // This method calculates the number of digits in the 152 | // sensor reading. Since each digit of the ASCII decimal 153 | // representation is a byte, the number of digits equals 154 | // the number of bytes: 155 | 156 | int getLength(int someValue) { 157 | // there's at least one byte: 158 | int digits = 1; 159 | // continually divide the value by ten, 160 | // adding one to the digit count for each 161 | // time you divide, until you're at 0: 162 | int dividend = someValue /10; 163 | while (dividend > 0) { 164 | dividend = dividend /10; 165 | digits++; 166 | } 167 | // return the number of digits: 168 | return digits; 169 | } 170 | 171 | void printWifiStatus() { 172 | // print the SSID of the network you're attached to: 173 | Serial.print("SSID: "); 174 | Serial.println(WiFi.SSID()); 175 | 176 | // print your WiFi shield's IP address: 177 | IPAddress ip = WiFi.localIP(); 178 | Serial.print("IP Address: "); 179 | Serial.println(ip); 180 | 181 | // print the received signal strength: 182 | long rssi = WiFi.RSSI(); 183 | Serial.print("signal strength (RSSI):"); 184 | Serial.print(rssi); 185 | Serial.println(" dBm"); 186 | } 187 | 188 | 189 | 190 | -------------------------------------------------------------------------------- /utility/QueueList.h: -------------------------------------------------------------------------------- 1 | /* 2 | * QueueList.h 3 | * 4 | * Library implementing a generic, dynamic queue (linked list version). 5 | * 6 | * --- 7 | * 8 | * Copyright (C) 2010 Efstathios Chatzikyriakidis (contact@efxa.org) 9 | * 10 | * This program is free software: you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation, either version 3 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program. If not, see . 22 | * 23 | * --- 24 | * 25 | * Version 1.0 26 | * 27 | * 2010-09-28 Efstathios Chatzikyriakidis 28 | * 29 | * - added exit(), blink(): error reporting and handling methods. 30 | * 31 | * 2010-09-25 Alexander Brevig 32 | * 33 | * - added setPrinter(): indirectly reference a Serial object. 34 | * 35 | * 2010-09-20 Efstathios Chatzikyriakidis 36 | * 37 | * - initial release of the library. 38 | * 39 | * --- 40 | * 41 | * For the latest version see: http://www.arduino.cc/ 42 | */ 43 | 44 | // header defining the interface of the source. 45 | #ifndef _QUEUELIST_H 46 | #define _QUEUELIST_H 47 | 48 | // include Arduino basic header. 49 | #include 50 | 51 | // the definition of the queue class. 52 | template 53 | class QueueList { 54 | public: 55 | // init the queue (constructor). 56 | QueueList (); 57 | 58 | // clear the queue (destructor). 59 | ~QueueList (); 60 | 61 | // push an item to the queue. 62 | void push (const T i); 63 | 64 | // pop an item from the queue. 65 | T pop (); 66 | 67 | // get an item from the queue. 68 | T peek () const; 69 | 70 | // check if the queue is empty. 71 | bool isEmpty () const; 72 | 73 | // get the number of items in the queue. 74 | int count () const; 75 | 76 | // set the printer of the queue. 77 | void setPrinter (Print & p); 78 | 79 | private: 80 | // exit report method in case of error. 81 | void exit (const char * m) const; 82 | 83 | // led blinking method in case of error. 84 | void blink () const; 85 | 86 | // the pin number of the on-board led. 87 | static const int ledPin = 13; 88 | 89 | // the structure of each node in the list. 90 | typedef struct node { 91 | T item; // the item in the node. 92 | node * next; // the next node in the list. 93 | } node; 94 | 95 | typedef node * link; // synonym for pointer to a node. 96 | 97 | Print * printer; // the printer of the queue. 98 | int size; // the size of the queue. 99 | link head; // the head of the list. 100 | link tail; // the tail of the list. 101 | }; 102 | 103 | // init the queue (constructor). 104 | template 105 | QueueList::QueueList () { 106 | size = 0; // set the size of queue to zero. 107 | head = NULL; // set the head of the list to point nowhere. 108 | tail = NULL; // set the tail of the list to point nowhere. 109 | printer = NULL; // set the printer of queue to point nowhere. 110 | } 111 | 112 | // clear the queue (destructor). 113 | template 114 | QueueList::~QueueList () { 115 | // deallocate memory space of each node in the list. 116 | for (link t = head; t != NULL; head = t) { 117 | t = head->next; delete head; 118 | } 119 | 120 | size = 0; // set the size of queue to zero. 121 | tail = NULL; // set the tail of the list to point nowhere. 122 | printer = NULL; // set the printer of queue to point nowhere. 123 | } 124 | 125 | // push an item to the queue. 126 | template 127 | void QueueList::push (const T i) { 128 | // create a temporary pointer to tail. 129 | link t = tail; 130 | 131 | // create a new node for the tail. 132 | tail = (link) new node; 133 | 134 | // if there is a memory allocation error. 135 | if (tail == NULL) 136 | exit ("QUEUE: insufficient memory to create a new node."); 137 | 138 | // set the next of the new node. 139 | tail->next = NULL; 140 | 141 | // store the item to the new node. 142 | tail->item = i; 143 | 144 | // check if the queue is empty. 145 | if (isEmpty ()) 146 | // make the new node the head of the list. 147 | head = tail; 148 | else 149 | // make the new node the tail of the list. 150 | t->next = tail; 151 | 152 | // increase the items. 153 | size++; 154 | } 155 | 156 | // pop an item from the queue. 157 | template 158 | T QueueList::pop () { 159 | // check if the queue is empty. 160 | if (isEmpty ()) 161 | exit ("QUEUE: can't pop item from queue: queue is empty."); 162 | 163 | // get the item of the head node. 164 | T item = head->item; 165 | 166 | // remove only the head node. 167 | link t = head->next; delete head; head = t; 168 | 169 | // decrease the items. 170 | size--; 171 | 172 | // return the item. 173 | return item; 174 | } 175 | 176 | // get an item from the queue. 177 | template 178 | T QueueList::peek () const { 179 | // check if the queue is empty. 180 | if (isEmpty ()) 181 | exit ("QUEUE: can't peek item from queue: queue is empty."); 182 | 183 | // return the item of the head node. 184 | return head->item; 185 | } 186 | 187 | // check if the queue is empty. 188 | template 189 | bool QueueList::isEmpty () const { 190 | return head == NULL; 191 | } 192 | 193 | // get the number of items in the queue. 194 | template 195 | int QueueList::count () const { 196 | return size; 197 | } 198 | 199 | // set the printer of the queue. 200 | template 201 | void QueueList::setPrinter (Print & p) { 202 | printer = &p; 203 | } 204 | 205 | // exit report method in case of error. 206 | template 207 | void QueueList::exit (const char * m) const { 208 | // print the message if there is a printer. 209 | if (printer) 210 | printer->println (m); 211 | 212 | // loop blinking until hardware reset. 213 | blink (); 214 | } 215 | 216 | // led blinking method in case of error. 217 | template 218 | void QueueList::blink () const { 219 | // set led pin as output. 220 | pinMode (ledPin, OUTPUT); 221 | 222 | // continue looping until hardware reset. 223 | while (true) { 224 | digitalWrite (ledPin, HIGH); // sets the LED on. 225 | delay (250); // pauses 1/4 of second. 226 | digitalWrite (ledPin, LOW); // sets the LED off. 227 | delay (250); // pauses 1/4 of second. 228 | } 229 | 230 | // solution selected due to lack of exit() and assert(). 231 | } 232 | 233 | #endif // _QUEUELIST_H 234 | -------------------------------------------------------------------------------- /WiFiRM04.h: -------------------------------------------------------------------------------- 1 | #ifndef WIFI_RM04_H 2 | #define WIFI_RM04_H 3 | 4 | #include 5 | 6 | extern "C" { 7 | #include "utility/wl_definitions.h" 8 | #include "utility/wl_types.h" 9 | } 10 | 11 | #include "IPAddress.h" 12 | #include "WiFiRM04Client.h" 13 | #include "WiFiRM04Server.h" 14 | 15 | class WiFiRM04Class 16 | { 17 | private: 18 | 19 | static void init(); 20 | public: 21 | static int16_t _state[MAX_SOCK_NUM]; 22 | static uint16_t _server_port[MAX_SOCK_NUM]; 23 | 24 | WiFiRM04Class(); 25 | 26 | /* 27 | * Get the first socket available 28 | */ 29 | static uint8_t getSocket(); 30 | 31 | /* 32 | * Get firmware version 33 | */ 34 | static char* firmwareVersion(); 35 | 36 | /* 37 | * Start Wifi as a AP 38 | */ 39 | static bool beginAsAp(char* ssid); 40 | 41 | 42 | /* Start Wifi connection for OPEN networks 43 | * 44 | * param ssid: Pointer to the SSID string. 45 | */ 46 | int begin(char* ssid); 47 | 48 | /* Start Wifi connection with WEP encryption. 49 | * Configure a key into the device. The key type (WEP-40, WEP-104) 50 | * is determined by the size of the key (5 bytes for WEP-40, 13 bytes for WEP-104). 51 | * 52 | * param ssid: Pointer to the SSID string. 53 | * param key_idx: The key index to set. Valid values are 0-3. 54 | * param key: Key input buffer. 55 | */ 56 | int begin(char* ssid, uint8_t key_idx, const char* key); 57 | 58 | /* Start Wifi connection with passphrase 59 | * the most secure supported mode will be automatically selected 60 | * 61 | * param ssid: Pointer to the SSID string. 62 | * param passphrase: Passphrase. Valid characters in a passphrase 63 | * must be between ASCII 32-126 (decimal). 64 | */ 65 | int begin(char* ssid, const char *passphrase); 66 | 67 | /* Change Ip configuration settings disabling the dhcp client 68 | * 69 | * param local_ip: Static ip configuration 70 | */ 71 | void config(IPAddress local_ip); 72 | 73 | /* Change Ip configuration settings disabling the dhcp client 74 | * 75 | * param local_ip: Static ip configuration 76 | * param dns_server: IP configuration for DNS server 1 77 | */ 78 | void config(IPAddress local_ip, IPAddress dns_server); 79 | 80 | /* Change Ip configuration settings disabling the dhcp client 81 | * 82 | * param local_ip: Static ip configuration 83 | * param dns_server: IP configuration for DNS server 1 84 | * param gateway : Static gateway configuration 85 | */ 86 | void config(IPAddress local_ip, IPAddress dns_server, IPAddress gateway); 87 | 88 | /* Change Ip configuration settings disabling the dhcp client 89 | * 90 | * param local_ip: Static ip configuration 91 | * param dns_server: IP configuration for DNS server 1 92 | * param gateway: Static gateway configuration 93 | * param subnet: Static Subnet mask 94 | */ 95 | void config(IPAddress local_ip, IPAddress dns_server, IPAddress gateway, IPAddress subnet); 96 | 97 | /* Change DNS Ip configuration 98 | * 99 | * param dns_server1: ip configuration for DNS server 1 100 | */ 101 | void setDNS(IPAddress dns_server1); 102 | 103 | /* Change DNS Ip configuration 104 | * 105 | * param dns_server1: ip configuration for DNS server 1 106 | * param dns_server2: ip configuration for DNS server 2 107 | * 108 | */ 109 | void setDNS(IPAddress dns_server1, IPAddress dns_server2); 110 | 111 | /* 112 | * Disconnect from the network 113 | * 114 | * return: one value of wl_status_t enum 115 | */ 116 | int disconnect(void); 117 | 118 | /* 119 | * Get the interface MAC address. 120 | * 121 | * return: pointer to uint8_t array with length WL_MAC_ADDR_LENGTH 122 | */ 123 | uint8_t* macAddress(uint8_t* mac); 124 | 125 | /* 126 | * Get the interface IP address. 127 | * 128 | * return: Ip address value 129 | */ 130 | IPAddress localIP(); 131 | 132 | /* 133 | * Get the interface subnet mask address. 134 | * 135 | * return: subnet mask address value 136 | */ 137 | IPAddress subnetMask(); 138 | 139 | /* 140 | * Get the gateway ip address. 141 | * 142 | * return: gateway ip address value 143 | */ 144 | IPAddress gatewayIP(); 145 | 146 | /* 147 | * Return the current SSID associated with the network 148 | * 149 | * return: ssid string 150 | */ 151 | char* SSID(); 152 | 153 | /* 154 | * Return the current BSSID associated with the network. 155 | * It is the MAC address of the Access Point 156 | * 157 | * return: pointer to uint8_t array with length WL_MAC_ADDR_LENGTH 158 | */ 159 | uint8_t* BSSID(uint8_t* bssid); 160 | 161 | /* 162 | * Return the current RSSI /Received Signal Strength in dBm) 163 | * associated with the network 164 | * 165 | * return: signed value 166 | */ 167 | int32_t RSSI(); 168 | 169 | /* 170 | * Return the Encryption Type associated with the network 171 | * 172 | * return: one value of wl_enc_type enum 173 | */ 174 | uint8_t encryptionType(); 175 | 176 | /* 177 | * Start scan WiFi networks available 178 | * 179 | * return: Number of discovered networks 180 | */ 181 | int8_t scanNetworks(); 182 | 183 | /* 184 | * Return the SSID discovered during the network scan. 185 | * 186 | * param networkItem: specify from which network item want to get the information 187 | * 188 | * return: ssid string of the specified item on the networks scanned list 189 | */ 190 | char* SSID(uint8_t networkItem); 191 | 192 | /* 193 | * Return the encryption type of the networks discovered during the scanNetworks 194 | * 195 | * param networkItem: specify from which network item want to get the information 196 | * 197 | * return: encryption type (enum wl_enc_type) of the specified item on the networks scanned list 198 | */ 199 | uint8_t encryptionType(uint8_t networkItem); 200 | 201 | /* 202 | * Return the RSSI of the networks discovered during the scanNetworks 203 | * 204 | * param networkItem: specify from which network item want to get the information 205 | * 206 | * return: signed value of RSSI of the specified item on the networks scanned list 207 | */ 208 | int32_t RSSI(uint8_t networkItem); 209 | 210 | /* 211 | * Return Connection status. 212 | * 213 | * return: one of the value defined in wl_status_t 214 | */ 215 | uint8_t status(); 216 | 217 | /* 218 | * Resolve the given hostname to an IP address. 219 | * param aHostname: Name to be resolved 220 | * param aResult: IPAddress structure to store the returned IP address 221 | * result: 1 if aIPAddrString was successfully converted to an IP address, 222 | * else error code 223 | */ 224 | int hostByName(const char* aHostname, IPAddress& aResult); 225 | 226 | friend class WiFiClientRM04; 227 | friend class WiFiServerRM04; 228 | }; 229 | 230 | extern WiFiRM04Class WiFi; 231 | 232 | #endif 233 | -------------------------------------------------------------------------------- /utility/wifi_drv.h: -------------------------------------------------------------------------------- 1 | #ifndef WiFi_Drv_h 2 | #define WiFi_Drv_h 3 | 4 | #include 5 | #include "wifi_spi.h" 6 | #include "IPAddress.h" 7 | #include "../WiFiRM04Udp.h" 8 | 9 | // Key index length 10 | #define KEY_IDX_LEN 1 11 | // 5 secs of delay to have the connection established 12 | #define WL_DELAY_START_CONNECTION 5000 13 | // firmware version string length 14 | #define WL_FW_VER_LENGTH 32 15 | 16 | class WiFiDrv 17 | { 18 | private: 19 | // settings of requested network 20 | static char _networkSsid[WL_NETWORKS_LIST_MAXNUM][WL_SSID_MAX_LENGTH+1]; 21 | static int32_t _networkRssi[WL_NETWORKS_LIST_MAXNUM]; 22 | static uint8_t _networkEncr[WL_NETWORKS_LIST_MAXNUM]; 23 | 24 | // firmware version string in the format a.b.c 25 | static char fwVersion[WL_FW_VER_LENGTH]; 26 | 27 | // settings of current selected network 28 | static char _ssid[WL_SSID_MAX_LENGTH+1]; 29 | static uint8_t _bssid[WL_MAC_ADDR_LENGTH]; 30 | static uint8_t _mac[WL_MAC_ADDR_LENGTH]; 31 | static uint8_t _localIp[WL_IPV4_LENGTH]; 32 | static uint8_t _subnetMask[WL_IPV4_LENGTH]; 33 | static uint8_t _gatewayIp[WL_IPV4_LENGTH]; 34 | 35 | /* 36 | * Get network Data information 37 | */ 38 | static void getNetworkData(uint8_t *ip, uint8_t *mask, uint8_t *gwip); 39 | 40 | static uint8_t reqHostByName(const char* aHostname); 41 | 42 | static int getHostByName(IPAddress& aResult); 43 | 44 | /* 45 | * Get remote Data information on UDP socket 46 | */ 47 | static void getRemoteData(uint8_t sock, uint8_t *ip, uint8_t *port); 48 | 49 | public: 50 | 51 | /* 52 | * Driver initialization 53 | */ 54 | static void wifiDriverInit(); 55 | 56 | /* 57 | * Set module to work as an opened(no password needed) AP(Access Point) 58 | * 59 | * param ssid: The broadcast ssid 60 | * param ssid_len: Lenght of ssid string. 61 | * return: true for success, false for failed 62 | */ 63 | static bool wifiSetApMode(char* ssid, uint8_t ssid_len); 64 | 65 | /* 66 | * Set the desired network which the connection manager should try to 67 | * connect to. 68 | * 69 | * The ssid of the desired network should be specified. 70 | * 71 | * param ssid: The ssid of the desired network. 72 | * param ssid_len: Lenght of ssid string. 73 | * return: WL_SUCCESS or WL_FAILURE 74 | */ 75 | static int8_t wifiSetNetwork(char* ssid, uint8_t ssid_len); 76 | 77 | /* Start Wifi connection with passphrase 78 | * the most secure supported mode will be automatically selected 79 | * 80 | * param ssid: Pointer to the SSID string. 81 | * param ssid_len: Lenght of ssid string. 82 | * param passphrase: Passphrase. Valid characters in a passphrase 83 | * must be between ASCII 32-126 (decimal). 84 | * param len: Lenght of passphrase string. 85 | * return: WL_SUCCESS or WL_FAILURE 86 | */ 87 | static int8_t wifiSetPassphrase(char* ssid, uint8_t ssid_len, const char *passphrase, const uint8_t len); 88 | 89 | /* Start Wifi connection with WEP encryption. 90 | * Configure a key into the device. The key type (WEP-40, WEP-104) 91 | * is determined by the size of the key (5 bytes for WEP-40, 13 bytes for WEP-104). 92 | * 93 | * param ssid: Pointer to the SSID string. 94 | * param ssid_len: Lenght of ssid string. 95 | * param key_idx: The key index to set. Valid values are 0-3. 96 | * param key: Key input buffer. 97 | * param len: Lenght of key string. 98 | * return: WL_SUCCESS or WL_FAILURE 99 | */ 100 | static int8_t wifiSetKey(char* ssid, uint8_t ssid_len, uint8_t key_idx, const void *key, const uint8_t len); 101 | 102 | /* Set ip configuration disabling dhcp client 103 | * 104 | * param validParams: set the number of parameters that we want to change 105 | * i.e. validParams = 1 means that we'll change only ip address 106 | * validParams = 3 means that we'll change ip address, gateway and netmask 107 | * param local_ip: Static ip configuration 108 | * param gateway: Static gateway configuration 109 | * param subnet: Static subnet mask configuration 110 | */ 111 | static void config(uint8_t validParams, uint32_t local_ip, uint32_t gateway, uint32_t subnet); 112 | 113 | /* Set DNS ip configuration 114 | * 115 | * param validParams: set the number of parameters that we want to change 116 | * i.e. validParams = 1 means that we'll change only dns_server1 117 | * validParams = 2 means that we'll change dns_server1 and dns_server2 118 | * param dns_server1: Static DNS server1 configuration 119 | * param dns_server2: Static DNS server2 configuration 120 | */ 121 | static void setDNS(uint8_t validParams, uint32_t dns_server1, uint32_t dns_server2); 122 | 123 | /* 124 | * Disconnect from the network 125 | * 126 | * return: WL_SUCCESS or WL_FAILURE 127 | */ 128 | static int8_t disconnect(); 129 | 130 | /* 131 | * Disconnect from the network 132 | * 133 | * return: one value of wl_status_t enum 134 | */ 135 | static uint8_t getConnectionStatus(); 136 | 137 | /* 138 | * Get the interface MAC address. 139 | * 140 | * return: pointer to uint8_t array with length WL_MAC_ADDR_LENGTH 141 | */ 142 | static uint8_t* getMacAddress(); 143 | 144 | /* 145 | * Get the interface IP address. 146 | * 147 | * return: copy the ip address value in IPAddress object 148 | */ 149 | static void getIpAddress(IPAddress& ip); 150 | 151 | /* 152 | * Get the interface subnet mask address. 153 | * 154 | * return: copy the subnet mask address value in IPAddress object 155 | */ 156 | static void getSubnetMask(IPAddress& mask); 157 | 158 | /* 159 | * Get the gateway ip address. 160 | * 161 | * return: copy the gateway ip address value in IPAddress object 162 | */ 163 | static void getGatewayIP(IPAddress& ip); 164 | 165 | /* 166 | * Return the current SSID associated with the network 167 | * 168 | * return: ssid string 169 | */ 170 | static char* getCurrentSSID(); 171 | 172 | /* 173 | * Return the current BSSID associated with the network. 174 | * It is the MAC address of the Access Point 175 | * 176 | * return: pointer to uint8_t array with length WL_MAC_ADDR_LENGTH 177 | */ 178 | static uint8_t* getCurrentBSSID(); 179 | 180 | /* 181 | * Return the current RSSI /Received Signal Strength in dBm) 182 | * associated with the network 183 | * 184 | * return: signed value 185 | */ 186 | static int32_t getCurrentRSSI(); 187 | 188 | /* 189 | * Return the Encryption Type associated with the network 190 | * 191 | * return: one value of wl_enc_type enum 192 | */ 193 | static uint8_t getCurrentEncryptionType(); 194 | 195 | /* 196 | * Start scan WiFi networks available 197 | * 198 | * return: Number of discovered networks 199 | */ 200 | static int8_t startScanNetworks(); 201 | 202 | /* 203 | * Get the networks available 204 | * 205 | * return: Number of discovered networks 206 | */ 207 | static uint8_t getScanNetworks(); 208 | 209 | /* 210 | * Return the SSID discovered during the network scan. 211 | * 212 | * param networkItem: specify from which network item want to get the information 213 | * 214 | * return: ssid string of the specified item on the networks scanned list 215 | */ 216 | static char* getSSIDNetoworks(uint8_t networkItem); 217 | 218 | /* 219 | * Return the RSSI of the networks discovered during the scanNetworks 220 | * 221 | * param networkItem: specify from which network item want to get the information 222 | * 223 | * return: signed value of RSSI of the specified item on the networks scanned list 224 | */ 225 | static int32_t getRSSINetoworks(uint8_t networkItem); 226 | 227 | /* 228 | * Return the encryption type of the networks discovered during the scanNetworks 229 | * 230 | * param networkItem: specify from which network item want to get the information 231 | * 232 | * return: encryption type (enum wl_enc_type) of the specified item on the networks scanned list 233 | */ 234 | static uint8_t getEncTypeNetowrks(uint8_t networkItem); 235 | 236 | /* 237 | * Resolve the given hostname to an IP address. 238 | * param aHostname: Name to be resolved 239 | * param aResult: IPAddress structure to store the returned IP address 240 | * result: 1 if aIPAddrString was successfully converted to an IP address, 241 | * else error code 242 | */ 243 | static int getHostByName(const char* aHostname, IPAddress& aResult); 244 | 245 | /* 246 | * Get the firmware version 247 | * result: version as string with this format a.b.c 248 | */ 249 | static char* getFwVersion(); 250 | 251 | friend class WiFiRM04UDP; 252 | 253 | }; 254 | 255 | extern WiFiDrv wiFiDrv; 256 | 257 | #endif 258 | -------------------------------------------------------------------------------- /utility/spi_drv.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Arduino.h" 3 | #include "spi_drv.h" 4 | #include "pins_arduino.h" 5 | //#define _DEBUG_ 6 | extern "C" { 7 | #include "debug.h" 8 | } 9 | 10 | #define DATAOUT 11 // MOSI 11 | #define DATAIN 12 // MISO 12 | #define SPICLOCK 13 // sck 13 | #define SLAVESELECT 10 // ss 14 | #define SLAVEREADY 7 // handshake pin 15 | #define WIFILED 9 // led on wifi shield 16 | 17 | #define DELAY_100NS do { asm volatile("nop"); }while(0); 18 | #define DELAY_SPI(X) { int ii=0; do { asm volatile("nop"); }while(++ii 0) && (_readChar != waitChar)); 103 | return (_readChar == waitChar); 104 | } 105 | 106 | int SpiDrv::readAndCheckChar(char checkChar, char* readChar) 107 | { 108 | getParam((uint8_t*)readChar); 109 | 110 | return (*readChar == checkChar); 111 | } 112 | 113 | char SpiDrv::readChar() 114 | { 115 | uint8_t readChar = 0; 116 | getParam(&readChar); 117 | return readChar; 118 | } 119 | 120 | #define WAIT_START_CMD(x) waitSpiChar(START_CMD) 121 | 122 | #define IF_CHECK_START_CMD(x) \ 123 | if (!WAIT_START_CMD(_data)) \ 124 | { \ 125 | TOGGLE_TRIGGER() \ 126 | WARN("Error waiting START_CMD"); \ 127 | return 0; \ 128 | }else \ 129 | 130 | #define CHECK_DATA(check, x) \ 131 | if (!readAndCheckChar(check, &x)) \ 132 | { \ 133 | TOGGLE_TRIGGER() \ 134 | WARN("Reply error"); \ 135 | INFO2(check, (uint8_t)x); \ 136 | return 0; \ 137 | }else \ 138 | 139 | #define waitSlaveReady() (digitalRead(SLAVEREADY) == LOW) 140 | #define waitSlaveSign() (digitalRead(SLAVEREADY) == HIGH) 141 | #define waitSlaveSignalH() while(digitalRead(SLAVEREADY) != HIGH){} 142 | #define waitSlaveSignalL() while(digitalRead(SLAVEREADY) != LOW){} 143 | 144 | void SpiDrv::waitForSlaveSign() 145 | { 146 | while (!waitSlaveSign()); 147 | } 148 | 149 | void SpiDrv::waitForSlaveReady() 150 | { 151 | while (!waitSlaveReady()); 152 | } 153 | 154 | void SpiDrv::getParam(uint8_t* param) 155 | { 156 | // Get Params data 157 | *param = spiTransfer(DUMMY_DATA); 158 | DELAY_TRANSFER(); 159 | } 160 | 161 | int SpiDrv::waitResponseCmd(uint8_t cmd, uint8_t numParam, uint8_t* param, uint8_t* param_len) 162 | { 163 | char _data = 0; 164 | int ii = 0; 165 | 166 | IF_CHECK_START_CMD(_data) 167 | { 168 | CHECK_DATA(cmd | REPLY_FLAG, _data){}; 169 | 170 | CHECK_DATA(numParam, _data); 171 | { 172 | readParamLen8(param_len); 173 | for (ii=0; ii<(*param_len); ++ii) 174 | { 175 | // Get Params data 176 | //param[ii] = spiTransfer(DUMMY_DATA); 177 | getParam(¶m[ii]); 178 | } 179 | } 180 | 181 | readAndCheckChar(END_CMD, &_data); 182 | } 183 | 184 | return 1; 185 | } 186 | /* 187 | int SpiDrv::waitResponse(uint8_t cmd, uint8_t numParam, uint8_t* param, uint16_t* param_len) 188 | { 189 | char _data = 0; 190 | int i =0, ii = 0; 191 | 192 | IF_CHECK_START_CMD(_data) 193 | { 194 | CHECK_DATA(cmd | REPLY_FLAG, _data){}; 195 | 196 | CHECK_DATA(numParam, _data); 197 | { 198 | readParamLen16(param_len); 199 | for (ii=0; ii<(*param_len); ++ii) 200 | { 201 | // Get Params data 202 | param[ii] = spiTransfer(DUMMY_DATA); 203 | } 204 | } 205 | 206 | readAndCheckChar(END_CMD, &_data); 207 | } 208 | 209 | return 1; 210 | } 211 | */ 212 | 213 | int SpiDrv::waitResponseData16(uint8_t cmd, uint8_t* param, uint16_t* param_len) 214 | { 215 | char _data = 0; 216 | uint16_t ii = 0; 217 | 218 | IF_CHECK_START_CMD(_data) 219 | { 220 | CHECK_DATA(cmd | REPLY_FLAG, _data){}; 221 | 222 | uint8_t numParam = readChar(); 223 | if (numParam != 0) 224 | { 225 | readParamLen16(param_len); 226 | for (ii=0; ii<(*param_len); ++ii) 227 | { 228 | // Get Params data 229 | param[ii] = spiTransfer(DUMMY_DATA); 230 | } 231 | } 232 | 233 | readAndCheckChar(END_CMD, &_data); 234 | } 235 | 236 | return 1; 237 | } 238 | 239 | int SpiDrv::waitResponseData8(uint8_t cmd, uint8_t* param, uint8_t* param_len) 240 | { 241 | char _data = 0; 242 | int ii = 0; 243 | 244 | IF_CHECK_START_CMD(_data) 245 | { 246 | CHECK_DATA(cmd | REPLY_FLAG, _data){}; 247 | 248 | uint8_t numParam = readChar(); 249 | if (numParam != 0) 250 | { 251 | readParamLen8(param_len); 252 | for (ii=0; ii<(*param_len); ++ii) 253 | { 254 | // Get Params data 255 | param[ii] = spiTransfer(DUMMY_DATA); 256 | } 257 | } 258 | 259 | readAndCheckChar(END_CMD, &_data); 260 | } 261 | 262 | return 1; 263 | } 264 | 265 | int SpiDrv::waitResponseParams(uint8_t cmd, uint8_t numParam, tParam* params) 266 | { 267 | char _data = 0; 268 | int i =0, ii = 0; 269 | 270 | 271 | IF_CHECK_START_CMD(_data) 272 | { 273 | CHECK_DATA(cmd | REPLY_FLAG, _data){}; 274 | 275 | uint8_t _numParam = readChar(); 276 | if (_numParam != 0) 277 | { 278 | for (i=0; i<_numParam; ++i) 279 | { 280 | params[i].paramLen = readParamLen8(); 281 | for (ii=0; ii maxNumParams) 317 | { 318 | numParam = maxNumParams; 319 | } 320 | *numParamRead = numParam; 321 | if (numParam != 0) 322 | { 323 | for (i=0; i maxNumParams) 362 | { 363 | numParam = maxNumParams; 364 | } 365 | *numParamRead = numParam; 366 | if (numParam != 0) 367 | { 368 | for (i=0; i>8)); 419 | spiTransfer((uint8_t)(param_len & 0xff)); 420 | } 421 | 422 | uint8_t SpiDrv::readParamLen8(uint8_t* param_len) 423 | { 424 | uint8_t _param_len = spiTransfer(DUMMY_DATA); 425 | if (param_len != NULL) 426 | { 427 | *param_len = _param_len; 428 | } 429 | return _param_len; 430 | } 431 | 432 | uint16_t SpiDrv::readParamLen16(uint16_t* param_len) 433 | { 434 | uint16_t _param_len = spiTransfer(DUMMY_DATA)<<8 | (spiTransfer(DUMMY_DATA)& 0xff); 435 | if (param_len != NULL) 436 | { 437 | *param_len = _param_len; 438 | } 439 | return _param_len; 440 | } 441 | 442 | 443 | void SpiDrv::sendBuffer(uint8_t* param, uint16_t param_len, uint8_t lastParam) 444 | { 445 | uint16_t i = 0; 446 | 447 | // Send Spi paramLen 448 | sendParamLen16(param_len); 449 | 450 | // Send Spi param data 451 | for (i=0; i>8)); 468 | spiTransfer((uint8_t)(param & 0xff)); 469 | 470 | // if lastParam==1 Send Spi END CMD 471 | if (lastParam == 1) 472 | spiTransfer(END_CMD); 473 | } 474 | 475 | /* Cmd Struct Message */ 476 | /* _________________________________________________________________________________ */ 477 | /*| START CMD | C/R | CMD |[TOT LEN]| N.PARAM | PARAM LEN | PARAM | .. | END CMD | */ 478 | /*|___________|______|______|_________|_________|___________|________|____|_________| */ 479 | /*| 8 bit | 1bit | 7bit | 8bit | 8bit | 8bit | nbytes | .. | 8bit | */ 480 | /*|___________|______|______|_________|_________|___________|________|____|_________| */ 481 | 482 | void SpiDrv::sendCmd(uint8_t cmd, uint8_t numParam) 483 | { 484 | // Send Spi START CMD 485 | spiTransfer(START_CMD); 486 | 487 | //waitForSlaveSign(); 488 | //wait the interrupt trigger on slave 489 | delayMicroseconds(SPI_START_CMD_DELAY); 490 | 491 | // Send Spi C + cmd 492 | spiTransfer(cmd & ~(REPLY_FLAG)); 493 | 494 | // Send Spi totLen 495 | //spiTransfer(totLen); 496 | 497 | // Send Spi numParam 498 | spiTransfer(numParam); 499 | 500 | // If numParam == 0 send END CMD 501 | if (numParam == 0) 502 | spiTransfer(END_CMD); 503 | 504 | } 505 | 506 | SpiDrv spiDrv; 507 | -------------------------------------------------------------------------------- /utility/at_drv.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "Arduino.h" 5 | #include "IPAddress.h" 6 | #include "at_drv.h" 7 | #include "pins_arduino.h" 8 | #define _DEBUG_ 9 | extern "C" { 10 | #include "debug.h" 11 | } 12 | 13 | // define USE_ESCAPE_PIN to use HW pin to switch mode 14 | #define USE_ESCAPE_PIN 15 | // use this pin to pull up/down module's ES/RTS pin to switch mode 16 | #define ESCAPE_PIN 21 17 | #define ESCAPE_PIN_ACTIVE LOW 18 | 19 | // CHECK_TCP_STATE is an experimental feature, disable it by default 20 | // #define CHECK_TCP_STATE 21 | 22 | // Suggest to use 38400, even using hardware UART 23 | #define DEFAULT_BAUD1 38400 24 | #define DEFAULT_BAUD2 38400 25 | 26 | // default Tes time should be 100 ms 27 | #define TES_TIME_IN_MS 100 28 | // defualt Tpt time should be 10ms 29 | #define TPT_TIME_IN_MS 10 30 | 31 | #define MAX_CMD_BUF_SIZE 64 32 | #define MAX_IP_BUF_SIZE 16 33 | #define MAX_WIFI_CONF_BUF_SIZE 64 34 | #define MAX_RESP_BUF_SIZE 64 35 | #define MAX_HOST_NAME_BUF_SIZE 128 36 | #define MAX_TEMP_BUF_SIZE 64 37 | #define MAX_DHCPD_IP_BUF_SIZE 128 38 | #define MAX_LINE_BUF_SIZE 512 39 | 40 | // use Serial1 as default serial port to communicate with WiFi module 41 | #define AT_DRV_SERIAL Serial1 42 | // use Serial2 to communicate the uart2 of our WiFi module 43 | #define AT_DRV_SERIAL1 Serial2 44 | 45 | // define the client socket port # 46 | #define SOCK0_LOCAL_PORT 1024 47 | #define SOCK1_LOCAL_PORT 1025 48 | 49 | 50 | const uint16_t localSockPort[] = {SOCK0_LOCAL_PORT, SOCK1_LOCAL_PORT}; 51 | 52 | char at_ok[] = "ok\r\n"; 53 | char at_Connected[] = "Connected\r\n"; 54 | char at_out_trans[] = "at+out_trans=0\r"; 55 | char *at_remoteip[2] = {"at+remoteip=%s\r\r", "at+C2_remoteip=%s\r\r"}; 56 | char *at_remoteport[2] = {"at+remoteport=%s\r\r", "at+C2_port=%s\r\r"}; 57 | char *at_CLport[2] = {"at+CLport=%s\r\r", "at+C2_CLport=%s\r\r"}; 58 | char at_wifi_conf[] = "at+wifi_conf=%s\r\r"; 59 | char at_wifi_ConState[] = "at+wifi_ConState=?\r\r"; 60 | char at_Get_MAC[] = "at+Get_MAC=?\r\r"; 61 | char at_netmode[] = "at+netmode=%c\r\r"; 62 | char at_net_commit[] = "at+net_commit=1\r\r"; 63 | char at_reconn[] = "at+reconn=1\r\r"; 64 | char *at_mode[2] = {"at+mode=%s\r\r" , "at+C2_mode=%s\r\r"}; 65 | char *at_remotepro[2] = {"at+remotepro=%s\r\r", "at+C2_protocol=%s\r\r"}; 66 | char at_dhcpd[] = "at+dhcpd=%c\r\r"; 67 | char at_dhcpd_ip[] = "at+dhcpd_ip=%s\r\r"; 68 | char at_dhcpd_dns[] = "at+dhcpd_dns=%s\r\r"; 69 | char at_dhcpd_time[] = "at+dhcpd_time=%s\r\r"; 70 | char at_net_ip[] = "at+net_ip=%s\r\r"; 71 | char at_net_dns[] = "at+net_dns=%s\r\r"; 72 | char *at_tcp_auto[2] = {"at+tcp_auto=%c\r\r" , "at+C2_tcp_auto=%c\r\r"}; 73 | char *at_timeout[2] = {"at+timeout=%s\r\r", "at+C2_timeout=%s\r\r"}; 74 | char at_tcp_port_stat[] = "at+excxxx=cat /proc/net/tcp | grep '[0-9]: [^0].*:%04X'> /dev/ttyS1"; 75 | char at_get_ip[] = "at+excxxx=ifconfig ra0 | grep 'inet addr:' | sed -e 's/inet addr:\\(.*\\).*Bcast:.*Mask:.*/\\1/' > /dev/ttyS1"; 76 | char at_get_mask[] = "at+excxxx=ifconfig ra0 | grep 'inet addr:' | sed -e 's/.*Mask:\\(.*\\)/\\1/' > /dev/ttyS1"; 77 | char at_get_gateway[] = "at+excxxx=cat /proc/net/route | grep -e 'ra0[[:space:]]\\+00000000' > /dev/ttyS1"; 78 | char at_get_ssid[] = "at+excxxx=iwconfig ra0 | grep ESSID | sed -e 's/.*ESSID:\"\\(.*\\)\".*Nickname:\".*\"/\\1/' > dev/ttyS1"; 79 | char at_get_bssid[] = "at+excxxx=iwconfig ra0 | grep 'Access Point' | sed -e 's/.*Access Point: \\(.*\\)/\\1/' > dev/ttyS1"; 80 | char at_get_rssi[] = "at+excxxx=iwconfig ra0 | grep 'Link Quality' | sed -e 's/.*Link Quality=\\(.*\\)\\/.*/\\1/' > dev/ttyS1"; 81 | char at_get_enc[] = "at+excxxx=iwpriv ra0 show EncrypType | sed -e 's/ra0.*show:[[:space:]]\\(.*\\).*/\\1/' > dev/ttyS1"; 82 | char at_wifi_Scan[] = "at+wifi_Scan=?\r\r"; 83 | char at_ver[] = "at+ver=?\r\r"; 84 | 85 | void AtDrv::begin() 86 | { 87 | serialPort[0]->begin(DEFAULT_BAUD1); 88 | serialPort[1]->begin(DEFAULT_BAUD2); 89 | clearSerialRxData(); 90 | } 91 | 92 | void AtDrv::end() { 93 | serialPort[0]->end(); 94 | serialPort[1]->end(); 95 | } 96 | 97 | bool AtDrv::isAtMode() 98 | { 99 | return atMode; 100 | } 101 | 102 | void AtDrv::setAtMode(bool mode) 103 | { 104 | atMode = mode; 105 | } 106 | 107 | bool AtDrv::echoTest(long timeout) 108 | { 109 | char buf[MAX_TEMP_BUF_SIZE+1]; 110 | int i; 111 | char *token; 112 | 113 | clearSerialRxData(); 114 | serialPort[0]->println("#32767"); 115 | serialPort[0]->flush(); 116 | serialPort[0]->setTimeout(timeout); 117 | i = serialPort[0]->readBytes(buf, MAX_TEMP_BUF_SIZE); 118 | if(i == 0) { 119 | INFO1("Echo No resp"); 120 | return false; 121 | } 122 | 123 | buf[i] = NULL; 124 | 125 | token = buf; 126 | while(*token && *token++ != '#'); 127 | 128 | int ret = strtol(token, NULL, 10); 129 | 130 | clearSerialRxData(); 131 | return (ret == 32767)? true:false; 132 | } 133 | 134 | void AtDrv::clearSerialRxData() 135 | { 136 | while(serialPort[0]->available()) 137 | serialPort[0]->read(); 138 | } 139 | 140 | #ifdef USE_ESCAPE_PIN 141 | bool AtDrv::switchToAtMode() 142 | { 143 | int retryCount = 0; 144 | // flush tx buffer's data first 145 | serialPort[0]->flush(); 146 | retry: 147 | digitalWrite(ESCAPE_PIN, ESCAPE_PIN_ACTIVE); 148 | // according to user manual, delay should be > Tes time, so we plus 50ms here 149 | delay(TES_TIME_IN_MS+50*(retryCount+1)); 150 | digitalWrite(ESCAPE_PIN, !ESCAPE_PIN_ACTIVE); 151 | 152 | // MUST preserve all data in rx buffer here, or these data would be mixed with at command response 153 | // TODO: QueueList would cause heap fragmentation? 154 | if(retryCount == 0 && sockConnected[0] == true) { 155 | while(serialPort[0]->available()) { 156 | sock0DataQueue.push(serialPort[0]->read()); 157 | } 158 | } 159 | 160 | if(echoTest()) { 161 | setAtMode(true); 162 | return true; 163 | } 164 | else 165 | setAtMode(false); 166 | 167 | if(retryCount++ < 5) 168 | goto retry; 169 | 170 | return false; 171 | } 172 | 173 | #else 174 | 175 | bool AtDrv::switchToAtMode() 176 | { 177 | // flush tx buffer's data first 178 | serialPort[0]->flush(); 179 | // preserve all data in rx buffer, or these data would be mixed with at command response 180 | // TODO: QueueList would cause heap fragmentation? 181 | if(sockConnected[0] == true) { 182 | while(serialPort[0]->available()) { 183 | sock0DataQueue.push(serialPort[0]->read()); 184 | } 185 | } 186 | 187 | if(isAtMode() && echoTest()) 188 | return true; 189 | 190 | // flush all first 191 | serialPort[0]->flush(); 192 | // according to user manual, delay should be greater than Tpt, so we plus 5ms here 193 | delay(TPT_TIME_IN_MS+5); 194 | serialPort[0]->write(0x2b); 195 | // flush every single byte to prevent buffering effect and cause wrong timing sequence 196 | serialPort[0]->flush(); 197 | delay(TPT_TIME_IN_MS+5); 198 | serialPort[0]->write(0x2b); 199 | serialPort[0]->flush(); 200 | delay(TPT_TIME_IN_MS+5); 201 | serialPort[0]->write(0x2b); 202 | serialPort[0]->flush(); 203 | // according to user manual, shuold be > 400ms < 600ms, so we use 500ms 204 | delay(500); 205 | serialPort[0]->write(0x1b); 206 | serialPort[0]->flush(); 207 | delay(TPT_TIME_IN_MS+5); 208 | serialPort[0]->write(0x1b); 209 | serialPort[0]->flush(); 210 | //delayMicroseconds(tptDealy); 211 | delay(TPT_TIME_IN_MS+5); 212 | serialPort[0]->write(0x1b); 213 | serialPort[0]->flush(); 214 | delay(TPT_TIME_IN_MS+5); 215 | 216 | if(echoTest()) { 217 | setAtMode(true); 218 | return true; 219 | } 220 | else 221 | setAtMode(false); 222 | 223 | return false; 224 | } 225 | #endif 226 | 227 | bool AtDrv::switchToDataMode(long timeout) 228 | { 229 | int retryCount = 0; 230 | 231 | if(!isAtMode()) 232 | return true; 233 | retry: 234 | clearSerialRxData(); 235 | INFO1(at_out_trans); 236 | serialPort[0]->print(at_out_trans); 237 | serialPort[0]->flush(); 238 | serialPort[0]->setTimeout(timeout); 239 | if(serialPort[0]->find(at_ok)) { 240 | setAtMode(false); 241 | return true; 242 | } 243 | 244 | if(retryCount++ < 5) 245 | goto retry; 246 | 247 | return false; 248 | } 249 | 250 | bool AtDrv::getRemoteIp(uint8_t sock, uint8_t *ip, long timeout) 251 | { 252 | bool ret = false; 253 | char cmdBuf[MAX_CMD_BUF_SIZE]; 254 | 255 | sprintf(cmdBuf, at_remoteip[sock], "?"); 256 | clearSerialRxData(); 257 | INFO1(cmdBuf); 258 | serialPort[0]->print(cmdBuf); 259 | serialPort[0]->flush(); 260 | serialPort[0]->setTimeout(timeout); 261 | if(!serialPort[0]->findUntil(cmdBuf, "\r\n")) { 262 | INFO1("fail to get remote IP"); 263 | ip[0] = ip[1] = ip[2] = ip[3] = 0; 264 | goto end; 265 | } 266 | 267 | ip[0] = serialPort[0]->parseInt(); 268 | ip[1] = serialPort[0]->parseInt(); 269 | ip[2] = serialPort[0]->parseInt(); 270 | ip[3] = serialPort[0]->parseInt(); 271 | 272 | INFO("Remote IP: %d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]); 273 | 274 | clearSerialRxData(); 275 | 276 | ret = true; 277 | end: 278 | return ret; 279 | } 280 | 281 | bool AtDrv::getLocalPort(uint8_t sock, uint16_t *port, long timeout) 282 | { 283 | bool ret = false; 284 | char cmdBuf[MAX_CMD_BUF_SIZE]; 285 | 286 | sprintf(cmdBuf, at_CLport[sock], "?"); 287 | clearSerialRxData(); 288 | INFO1(cmdBuf); 289 | serialPort[0]->print(cmdBuf); 290 | serialPort[0]->flush(); 291 | serialPort[0]->setTimeout(timeout); 292 | if(!serialPort[0]->find(cmdBuf)) { 293 | INFO1("fail to get remote port"); 294 | *port = 0; 295 | goto end; 296 | } 297 | 298 | *port = serialPort[0]->parseInt(); 299 | 300 | INFO("Local port: %d", *port); 301 | 302 | clearSerialRxData(); 303 | 304 | ret = true; 305 | end: 306 | return ret; 307 | } 308 | 309 | bool AtDrv::getRemotePort(uint8_t sock, uint16_t *port, long timeout) 310 | { 311 | bool ret = false; 312 | char cmdBuf[MAX_CMD_BUF_SIZE]; 313 | 314 | sprintf(cmdBuf, at_remoteport[sock], "?"); 315 | clearSerialRxData(); 316 | INFO1(cmdBuf); 317 | serialPort[0]->print(cmdBuf); 318 | serialPort[0]->flush(); 319 | serialPort[0]->setTimeout(timeout); 320 | if(!serialPort[0]->find(cmdBuf)) { 321 | INFO1("fail to get remote port"); 322 | *port = 0; 323 | goto end; 324 | } 325 | 326 | *port = serialPort[0]->parseInt(); 327 | 328 | INFO("Remote port: %d", *port); 329 | 330 | clearSerialRxData(); 331 | 332 | ret = true; 333 | end: 334 | return ret; 335 | } 336 | 337 | void AtDrv::getRemoteData(uint8_t sock, uint8_t *ip, uint16_t *port) 338 | { 339 | if(!isAtMode()) { 340 | if(!switchToAtMode()) { 341 | INFO1("Can't switch to at mode"); 342 | memset(ip, 0, 4); 343 | *port = 0; 344 | goto end; 345 | } 346 | } 347 | 348 | getRemoteIp(sock, ip); 349 | getRemotePort(sock, port); 350 | 351 | end: 352 | return; 353 | } 354 | 355 | void AtDrv::getLocalIp(uint8_t *ip, long timeout) 356 | { 357 | clearSerialRxData(); 358 | INFO1(at_get_ip); 359 | serialPort[0]->print(at_get_ip); 360 | serialPort[0]->print("\r\r"); 361 | serialPort[0]->flush(); 362 | serialPort[0]->setTimeout(timeout); 363 | 364 | // skip cmd response 365 | if(!serialPort[0]->find(at_get_ip)) { 366 | INFO1("fail to get local IP"); 367 | ip[0] = ip[1] = ip[2] = ip[3] = 0; 368 | goto end; 369 | } 370 | 371 | ip[0] = serialPort[0]->parseInt(); 372 | ip[1] = serialPort[0]->parseInt(); 373 | ip[2] = serialPort[0]->parseInt(); 374 | ip[3] = serialPort[0]->parseInt(); 375 | 376 | INFO("Local IP: %d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]); 377 | 378 | end: 379 | clearSerialRxData(); 380 | return; 381 | } 382 | 383 | void AtDrv::getNetmask(uint8_t *mask, long timeout) 384 | { 385 | clearSerialRxData(); 386 | INFO1(at_get_mask); 387 | serialPort[0]->print(at_get_mask); 388 | serialPort[0]->print("\r\r"); 389 | serialPort[0]->flush(); 390 | serialPort[0]->setTimeout(timeout); 391 | 392 | // skip cmd response 393 | if(!serialPort[0]->find(at_get_mask)) { 394 | INFO1("fail to get netmask"); 395 | mask[0] = mask[1] = mask[2] = mask[3] = 0; 396 | goto end; 397 | } 398 | 399 | mask[0] = serialPort[0]->parseInt(); 400 | mask[1] = serialPort[0]->parseInt(); 401 | mask[2] = serialPort[0]->parseInt(); 402 | mask[3] = serialPort[0]->parseInt(); 403 | 404 | INFO("Netmask: %d.%d.%d.%d", mask[0], mask[1], mask[2], mask[3]); 405 | 406 | end: 407 | clearSerialRxData(); 408 | return; 409 | } 410 | 411 | void AtDrv::getGateway(uint8_t *gwip, long timeout) 412 | { 413 | int bytes; 414 | int start; 415 | char lineBuf[MAX_LINE_BUF_SIZE]; 416 | char *token; 417 | 418 | clearSerialRxData(); 419 | INFO1(at_get_gateway); 420 | serialPort[0]->print(at_get_gateway); 421 | serialPort[0]->print("\r\r"); 422 | serialPort[0]->flush(); 423 | serialPort[0]->setTimeout(timeout); 424 | 425 | // skip cmd response && skip until "00000000" 426 | if(!serialPort[0]->find(at_get_gateway) || !serialPort[0]->find("00000000")) { 427 | INFO1("fail to get gateway"); 428 | gwip[0] = gwip[1] = gwip[2] = gwip[3] = 0; 429 | goto end; 430 | } 431 | 432 | bytes = serialPort[0]->readBytesUntil('\n', lineBuf, MAX_LINE_BUF_SIZE); 433 | if(bytes >= MAX_LINE_BUF_SIZE) { 434 | INFO1("Buffer is not enough"); 435 | goto end; 436 | } 437 | 438 | token = strtok(lineBuf, " \t"); 439 | 440 | if(token) 441 | *((uint32_t *)gwip) = strtol(token, NULL, 16); 442 | else { 443 | INFO1("fail to parse netmask"); 444 | gwip[0] = gwip[1] = gwip[2] = gwip[3] = 0; 445 | goto end; 446 | } 447 | 448 | INFO("Gateway: %d.%d.%d.%d", gwip[0], gwip[1], gwip[2], gwip[3]); 449 | 450 | end: 451 | clearSerialRxData(); 452 | return; 453 | } 454 | 455 | void AtDrv::getNetworkData(uint8_t *ip, uint8_t *mask, uint8_t *gwip) 456 | { 457 | if(!isAtMode()) { 458 | if(!switchToAtMode()) { 459 | INFO1("Can't switch to at mode"); 460 | memset(ip, 0, 4); 461 | memcpy(mask, 0, 4); 462 | memcpy(gwip, 0, 4); 463 | goto end; 464 | } 465 | } 466 | 467 | getLocalIp(ip); 468 | getNetmask(mask); 469 | getGateway(gwip); 470 | 471 | end: 472 | return; 473 | } 474 | 475 | bool AtDrv::isWiFiConnected(long timeout) 476 | { 477 | bool ret = false; 478 | byte respBuf[MAX_RESP_BUF_SIZE]; 479 | 480 | if(!isAtMode()) { 481 | if(!switchToAtMode()) { 482 | INFO1("Can't switch to at mode"); 483 | goto end; 484 | } 485 | } 486 | 487 | clearSerialRxData(); 488 | INFO1(at_wifi_ConState); 489 | serialPort[0]->print(at_wifi_ConState); 490 | serialPort[0]->flush(); 491 | serialPort[0]->setTimeout(timeout); 492 | if(!serialPort[0]->find(at_Connected)) { 493 | INFO1("Not Connected"); 494 | goto end; 495 | } 496 | ret = true; 497 | end: 498 | return ret; 499 | } 500 | 501 | bool AtDrv::setWiFiConfig(char *ssid, int type, const char * password, long timeout) 502 | { 503 | bool ret = false; 504 | char wifiConfBuf[MAX_WIFI_CONF_BUF_SIZE]; 505 | char conSetting[MAX_TEMP_BUF_SIZE]; 506 | 507 | if(type == ENC_TYPE_NONE) 508 | sprintf(conSetting, "%s,none,", ssid); 509 | else if(type == ENC_TYPE_WEP_OPEN) 510 | sprintf(conSetting, "%s,wep_open,%s", ssid, password); 511 | else 512 | sprintf(conSetting, "%s,auto,%s", ssid, password); 513 | 514 | sprintf(wifiConfBuf, at_wifi_conf, conSetting); 515 | 516 | clearSerialRxData(); 517 | INFO1(wifiConfBuf); 518 | serialPort[0]->print(wifiConfBuf); 519 | serialPort[0]->flush(); 520 | serialPort[0]->setTimeout(timeout); 521 | if(!serialPort[0]->find(wifiConfBuf) || !serialPort[0]->find(at_ok)) { 522 | INFO1("Fail to set wifi conf"); 523 | goto end; 524 | } 525 | 526 | ret = true; 527 | end: 528 | return ret; 529 | } 530 | 531 | bool AtDrv::setNetMode(int netMode, long timeout) 532 | { 533 | bool ret = false; 534 | char netModeBuf[MAX_TEMP_BUF_SIZE]; 535 | 536 | sprintf(netModeBuf, at_netmode, '0'+netMode); 537 | 538 | clearSerialRxData(); 539 | INFO1(netModeBuf); 540 | serialPort[0]->print(netModeBuf); 541 | serialPort[0]->flush(); 542 | serialPort[0]->setTimeout(timeout); 543 | if(!serialPort[0]->find(netModeBuf) || !serialPort[0]->find(at_ok)) { 544 | INFO1("Fail to set net mode"); 545 | goto end; 546 | } 547 | 548 | ret = true; 549 | end: 550 | return ret; 551 | } 552 | 553 | void AtDrv::netCommit() 554 | { 555 | clearSerialRxData(); 556 | INFO1(at_net_commit); 557 | serialPort[0]->print(at_net_commit); 558 | serialPort[0]->flush(); 559 | delay(30000); 560 | // No any response 561 | } 562 | 563 | bool AtDrv::reConnect(long timeout) 564 | { 565 | bool ret = false; 566 | 567 | clearSerialRxData(); 568 | INFO1(at_reconn); 569 | serialPort[0]->print(at_reconn); 570 | serialPort[0]->flush(); 571 | serialPort[0]->setTimeout(timeout); 572 | if(!serialPort[0]->find(at_reconn) || !serialPort[0]->find(at_ok)) { 573 | INFO1("Fail to reconnect"); 574 | goto end; 575 | } 576 | setAtMode(false); 577 | #ifndef CHECK_TCP_STATE 578 | // Since we don't know port status, try to wait 5 sec. anyway 579 | delay(5000); 580 | #endif 581 | clearSerialRxData(); 582 | ret = true; 583 | end: 584 | return ret; 585 | } 586 | 587 | bool AtDrv::getTcpAuto(uint8_t sock, bool *enable, long timeout) 588 | { 589 | bool ret = false; 590 | char tcpAutoBuf[MAX_TEMP_BUF_SIZE]; 591 | 592 | sprintf(tcpAutoBuf, at_tcp_auto[sock], '?'); 593 | 594 | clearSerialRxData(); 595 | INFO1(tcpAutoBuf); 596 | serialPort[0]->print(tcpAutoBuf); 597 | serialPort[0]->flush(); 598 | serialPort[0]->setTimeout(timeout); 599 | if(!serialPort[0]->find(tcpAutoBuf)) { 600 | INFO1("Fail to get tcp auto"); 601 | goto end; 602 | } 603 | 604 | *enable = serialPort[0]->parseInt(); 605 | 606 | INFO("tcp auto: %d", *enable); 607 | 608 | clearSerialRxData(); 609 | 610 | ret = true; 611 | end: 612 | return ret; 613 | } 614 | 615 | bool AtDrv::setTcpAuto(uint8_t sock, bool enable, long timeout) 616 | { 617 | bool ret = false; 618 | char tcpAutoBuf[MAX_TEMP_BUF_SIZE]; 619 | 620 | if(enable) 621 | sprintf(tcpAutoBuf, at_tcp_auto[sock], '1'); 622 | else 623 | sprintf(tcpAutoBuf, at_tcp_auto[sock], '0'); 624 | 625 | clearSerialRxData(); 626 | INFO1(tcpAutoBuf); 627 | serialPort[0]->print(tcpAutoBuf); 628 | serialPort[0]->flush(); 629 | serialPort[0]->setTimeout(timeout); 630 | if(!serialPort[0]->find(tcpAutoBuf) || !serialPort[0]->find(at_ok)) { 631 | INFO1("Fail to set tcp auto"); 632 | goto end; 633 | } 634 | 635 | ret = true; 636 | end: 637 | return ret; 638 | } 639 | 640 | bool AtDrv::setDhcpd(bool enable, long timeout) 641 | { 642 | bool ret = false; 643 | char dhcpdBuf[MAX_TEMP_BUF_SIZE]; 644 | 645 | if(enable) 646 | sprintf(dhcpdBuf, at_dhcpd, '1'); 647 | else 648 | sprintf(dhcpdBuf, at_dhcpd, '0'); 649 | 650 | clearSerialRxData(); 651 | INFO1(dhcpdBuf); 652 | serialPort[0]->print(dhcpdBuf); 653 | serialPort[0]->flush(); 654 | serialPort[0]->setTimeout(timeout); 655 | if(!serialPort[0]->find(dhcpdBuf) || !serialPort[0]->find(at_ok)) { 656 | INFO1("Fail to set dhcpd"); 657 | goto end; 658 | } 659 | 660 | ret = true; 661 | end: 662 | return ret; 663 | } 664 | 665 | bool AtDrv::setDhcpdIp(uint32_t ipStart, uint32_t ipEnd, uint32_t mask, uint32_t gateway, long timeout) 666 | { 667 | bool ret = false; 668 | char dhcpIpBuf[MAX_DHCPD_IP_BUF_SIZE]; 669 | char tempBuf[MAX_DHCPD_IP_BUF_SIZE]; 670 | char ipStartBuf[MAX_IP_BUF_SIZE]; 671 | char ipEndBuf[MAX_IP_BUF_SIZE]; 672 | char maskBuf[MAX_IP_BUF_SIZE]; 673 | char gatewayBuf[MAX_IP_BUF_SIZE]; 674 | 675 | uint8_t *pIp = (uint8_t*) &ipStart; 676 | sprintf(ipStartBuf, "%u.%u.%u.%u", pIp[0], pIp[1], pIp[2], pIp[3]); 677 | 678 | pIp = (uint8_t*) &ipEnd; 679 | sprintf(ipEndBuf, "%u.%u.%u.%u", pIp[0], pIp[1], pIp[2], pIp[3]); 680 | 681 | pIp = (uint8_t*) &mask; 682 | sprintf(maskBuf, "%u.%u.%u.%u", pIp[0], pIp[1], pIp[2], pIp[3]); 683 | 684 | pIp = (uint8_t*) &gateway; 685 | sprintf(gatewayBuf, "%u.%u.%u.%u", pIp[0], pIp[1], pIp[2], pIp[3]); 686 | 687 | sprintf(tempBuf, "%s,%s,%s,%s", ipStartBuf, ipEndBuf, maskBuf, gatewayBuf); 688 | 689 | sprintf(dhcpIpBuf, at_dhcpd_ip, tempBuf); 690 | 691 | clearSerialRxData(); 692 | INFO1(dhcpIpBuf); 693 | serialPort[0]->print(dhcpIpBuf); 694 | serialPort[0]->flush(); 695 | serialPort[0]->setTimeout(timeout); 696 | if(!serialPort[0]->find(dhcpIpBuf) || !serialPort[0]->find(at_ok)) { 697 | INFO1("Fail to set dhcpd ip"); 698 | goto end; 699 | } 700 | 701 | ret = true; 702 | end: 703 | return ret; 704 | } 705 | 706 | bool AtDrv::setDhcpdDns(uint32_t dns1, uint32_t dns2, long timeout) 707 | { 708 | bool ret = false; 709 | char dhcpDnsBuf[MAX_DHCPD_IP_BUF_SIZE]; 710 | char tempBuf[MAX_DHCPD_IP_BUF_SIZE]; 711 | char dns1Buf[MAX_IP_BUF_SIZE]; 712 | char dns2Buf[MAX_IP_BUF_SIZE]; 713 | 714 | uint8_t *pIp = (uint8_t*) &dns1; 715 | sprintf(dns1Buf, "%u.%u.%u.%u", pIp[0], pIp[1], pIp[2], pIp[3]); 716 | 717 | pIp = (uint8_t*) &dns2; 718 | sprintf(dns2Buf, "%u.%u.%u.%u", pIp[0], pIp[1], pIp[2], pIp[3]); 719 | 720 | sprintf(tempBuf, "%s,%s", dns1Buf, dns2Buf); 721 | 722 | sprintf(dhcpDnsBuf, at_dhcpd_dns, tempBuf); 723 | 724 | clearSerialRxData(); 725 | INFO1(dhcpDnsBuf); 726 | serialPort[0]->print(dhcpDnsBuf); 727 | serialPort[0]->flush(); 728 | serialPort[0]->setTimeout(timeout); 729 | if(!serialPort[0]->find(dhcpDnsBuf) || !serialPort[0]->find(at_ok)) { 730 | INFO1("Fail to set dhcpd dns"); 731 | goto end; 732 | } 733 | 734 | ret = true; 735 | end: 736 | return ret; 737 | } 738 | 739 | bool AtDrv::setDhcpdTime(uint32_t time, long timeout) 740 | { 741 | bool ret = false; 742 | char dhcpTimeBuf[MAX_TEMP_BUF_SIZE]; 743 | char timeBuf[MAX_TEMP_BUF_SIZE]; 744 | 745 | sprintf(timeBuf, "%u", time); 746 | sprintf(dhcpTimeBuf, at_dhcpd_time, timeBuf); 747 | 748 | clearSerialRxData(); 749 | INFO1(dhcpTimeBuf); 750 | serialPort[0]->print(dhcpTimeBuf); 751 | serialPort[0]->flush(); 752 | serialPort[0]->setTimeout(timeout); 753 | if(!serialPort[0]->find(dhcpTimeBuf) || !serialPort[0]->find(at_ok)) { 754 | INFO1("Fail to set dhcpd time"); 755 | goto end; 756 | } 757 | 758 | ret = true; 759 | end: 760 | return ret; 761 | } 762 | 763 | bool AtDrv::getNetworkTimeout(uint8_t sock, uint32_t *time, long timeout) 764 | { 765 | bool ret = false; 766 | char timeoutBuf[MAX_TEMP_BUF_SIZE]; 767 | 768 | sprintf(timeoutBuf, at_timeout[sock], "?"); 769 | 770 | clearSerialRxData(); 771 | INFO1(timeoutBuf); 772 | serialPort[0]->print(timeoutBuf); 773 | serialPort[0]->flush(); 774 | serialPort[0]->setTimeout(timeout); 775 | if(!serialPort[0]->find(timeoutBuf)) { 776 | INFO1("Fail to set timeout"); 777 | goto end; 778 | } 779 | 780 | *time = serialPort[0]->parseInt(); 781 | ret = true; 782 | clearSerialRxData(); 783 | end: 784 | return ret; 785 | } 786 | 787 | bool AtDrv::setNetworkTimeout(uint8_t sock, uint32_t time, long timeout) 788 | { 789 | bool ret = false; 790 | char timeoutBuf[MAX_TEMP_BUF_SIZE]; 791 | char timeBuf[MAX_TEMP_BUF_SIZE]; 792 | 793 | sprintf(timeBuf, "%u", time); 794 | sprintf(timeoutBuf, at_timeout[sock], timeBuf); 795 | 796 | clearSerialRxData(); 797 | INFO1(timeoutBuf); 798 | serialPort[0]->print(timeoutBuf); 799 | serialPort[0]->flush(); 800 | serialPort[0]->setTimeout(timeout); 801 | if(!serialPort[0]->find(timeoutBuf) || !serialPort[0]->find(at_ok)) { 802 | INFO1("Fail to set timeout"); 803 | goto end; 804 | } 805 | 806 | ret = true; 807 | end: 808 | return ret; 809 | } 810 | 811 | bool AtDrv::setNetIp(uint32_t ip, uint32_t mask, uint32_t gateway, long timeout) 812 | { 813 | bool ret = false; 814 | char netIpBuf[MAX_DHCPD_IP_BUF_SIZE]; 815 | char tempBuf[MAX_DHCPD_IP_BUF_SIZE]; 816 | char ipBuf[MAX_IP_BUF_SIZE]; 817 | char maskBuf[MAX_IP_BUF_SIZE]; 818 | char gatewayBuf[MAX_IP_BUF_SIZE]; 819 | 820 | uint8_t *pIp = (uint8_t*) &ip; 821 | sprintf(ipBuf, "%u.%u.%u.%u", pIp[0], pIp[1], pIp[2], pIp[3]); 822 | 823 | pIp = (uint8_t*) &mask; 824 | sprintf(maskBuf, "%u.%u.%u.%u", pIp[0], pIp[1], pIp[2], pIp[3]); 825 | 826 | pIp = (uint8_t*) &gateway; 827 | sprintf(gatewayBuf, "%u.%u.%u.%u", pIp[0], pIp[1], pIp[2], pIp[3]); 828 | 829 | sprintf(tempBuf, "%s,%s,%s", ipBuf, maskBuf, gatewayBuf); 830 | 831 | sprintf(netIpBuf, at_net_ip, tempBuf); 832 | 833 | clearSerialRxData(); 834 | INFO1(netIpBuf); 835 | serialPort[0]->print(netIpBuf); 836 | serialPort[0]->flush(); 837 | serialPort[0]->setTimeout(timeout); 838 | if(!serialPort[0]->find(netIpBuf) || !serialPort[0]->find(at_ok)) { 839 | INFO1("Fail to set net ip"); 840 | goto end; 841 | } 842 | 843 | ret = true; 844 | end: 845 | return ret; 846 | } 847 | 848 | bool AtDrv::setNetDns(uint32_t dns1, uint32_t dns2, long timeout) 849 | { 850 | bool ret = false; 851 | char netDnsBuf[MAX_DHCPD_IP_BUF_SIZE]; 852 | char tempBuf[MAX_DHCPD_IP_BUF_SIZE]; 853 | char dns1Buf[MAX_IP_BUF_SIZE]; 854 | char dns2Buf[MAX_IP_BUF_SIZE]; 855 | 856 | uint8_t *pIp = (uint8_t*) &dns1; 857 | sprintf(dns1Buf, "%u.%u.%u.%u", pIp[0], pIp[1], pIp[2], pIp[3]); 858 | 859 | pIp = (uint8_t*) &dns2; 860 | sprintf(dns2Buf, "%u.%u.%u.%u", pIp[0], pIp[1], pIp[2], pIp[3]); 861 | 862 | sprintf(tempBuf, "%s,%s", dns1Buf, dns2Buf); 863 | 864 | sprintf(netDnsBuf, at_net_dns, tempBuf); 865 | 866 | clearSerialRxData(); 867 | INFO1(netDnsBuf); 868 | serialPort[0]->print(netDnsBuf); 869 | serialPort[0]->flush(); 870 | serialPort[0]->setTimeout(timeout); 871 | if(!serialPort[0]->find(netDnsBuf) || !serialPort[0]->find(at_ok)) { 872 | INFO1("Fail to set dhcpd dns"); 873 | goto end; 874 | } 875 | 876 | ret = true; 877 | end: 878 | return ret; 879 | } 880 | 881 | bool AtDrv::setApSSID(char *ssid, int type, const char *password) 882 | { 883 | bool ret = false; 884 | IPAddress ipStart(192, 168, 43, 100); 885 | IPAddress ipEnd(192, 168, 43, 200); 886 | IPAddress mask(255, 255, 255, 0); 887 | IPAddress gateway(192, 168, 43, 1); 888 | IPAddress dns1(192, 168, 43, 1); 889 | IPAddress dns2(8, 8, 8, 8); 890 | IPAddress netIp(192, 168, 43, 1); 891 | 892 | if(!isAtMode()) { 893 | if(!switchToAtMode()) { 894 | INFO1("Can't switch to at mode"); 895 | goto end; 896 | } 897 | } 898 | 899 | if(!setNetMode(NET_MODE_WIFI_AP)) 900 | goto end; 901 | 902 | if(!setWiFiConfig(ssid, type, password)) 903 | goto end; 904 | 905 | if(!setDhcpd(true)) 906 | goto end; 907 | 908 | if(!setDhcpdIp(ipStart, ipEnd, mask, gateway)) 909 | goto end; 910 | 911 | if(!setDhcpdDns(dns1, dns2)) 912 | goto end; 913 | 914 | if(!setDhcpdTime(86400)) 915 | goto end; 916 | 917 | if(!setNetIp(netIp, mask, gateway)) 918 | goto end; 919 | 920 | if(!setNetDns(dns1, dns2)) 921 | goto end; 922 | 923 | netCommit(); 924 | 925 | ret = true; 926 | end: 927 | return ret; 928 | } 929 | 930 | bool AtDrv::setSSID(char *ssid, int type, const char *password) 931 | { 932 | bool ret = false; 933 | 934 | if(!isAtMode()) { 935 | if(!switchToAtMode()) { 936 | INFO1("Can't switch to at mode"); 937 | goto end; 938 | } 939 | } 940 | 941 | if(!setNetMode(NET_MODE_WIFI_CLIENT)) 942 | goto end; 943 | 944 | if(!setWiFiConfig(ssid, type, password)) 945 | goto end; 946 | 947 | netCommit(); 948 | 949 | ret = true; 950 | end: 951 | return ret; 952 | } 953 | 954 | bool AtDrv::getMAC(uint8_t *mac, long timeout) 955 | { 956 | bool ret = false; 957 | char buf[MAX_TEMP_BUF_SIZE]; 958 | int bytes; 959 | int i = 0; 960 | char *token; 961 | 962 | memset(mac, 0, WL_MAC_ADDR_LENGTH); 963 | 964 | if(!isAtMode()) { 965 | if(!switchToAtMode()) { 966 | INFO1("Can't switch to at mode"); 967 | goto end; 968 | } 969 | } 970 | 971 | clearSerialRxData(); 972 | INFO1(at_Get_MAC); 973 | serialPort[0]->print(at_Get_MAC); 974 | serialPort[0]->flush(); 975 | serialPort[0]->setTimeout(timeout); 976 | if(!serialPort[0]->find(at_Get_MAC)) { 977 | INFO1("Fail to get MAC"); 978 | goto end; 979 | } 980 | 981 | bytes = serialPort[0]->readBytes(buf, MAX_TEMP_BUF_SIZE); 982 | 983 | if(bytes >= MAX_TEMP_BUF_SIZE) { 984 | INFO1("Buffer is not enough"); 985 | goto end; 986 | } 987 | 988 | buf[bytes] = NULL; 989 | token = strtok(buf, " :,\r\n"); 990 | 991 | while(token != NULL && i < WL_MAC_ADDR_LENGTH) { 992 | mac[WL_MAC_ADDR_LENGTH-1-i] = strtol(token, NULL, 16); 993 | token = strtok(NULL, " :,\r\n"); 994 | i++; 995 | } 996 | 997 | if(i!=6) { 998 | INFO1("Can't get valid MAC string"); 999 | INFO1(buf); 1000 | memset(mac, 0, WL_MAC_ADDR_LENGTH); 1001 | goto end; 1002 | } 1003 | 1004 | ret = true; 1005 | end: 1006 | return ret; 1007 | } 1008 | 1009 | bool AtDrv::getMode(uint8_t sock, int *mode, long timeout) 1010 | { 1011 | bool ret = false; 1012 | int bytes; 1013 | char modeBuf[MAX_TEMP_BUF_SIZE]; 1014 | 1015 | sprintf(modeBuf, at_mode[sock], "?"); 1016 | 1017 | clearSerialRxData(); 1018 | INFO1(modeBuf); 1019 | serialPort[0]->print(modeBuf); 1020 | serialPort[0]->flush(); 1021 | serialPort[0]->setTimeout(timeout); 1022 | if(!serialPort[0]->find(modeBuf)) { 1023 | INFO1("Fail to get mode"); 1024 | goto end; 1025 | } 1026 | 1027 | bytes = serialPort[0]->readBytes(modeBuf, MAX_TEMP_BUF_SIZE); 1028 | 1029 | if(bytes >= MAX_TEMP_BUF_SIZE) { 1030 | INFO1("Buffer is not enough"); 1031 | goto end; 1032 | } 1033 | 1034 | modeBuf[bytes] = NULL; 1035 | 1036 | if(sock == 0) { 1037 | if(strstr(modeBuf, "server")) { 1038 | *mode = MODE_SERVER; 1039 | ret = true; 1040 | 1041 | } 1042 | else if(strstr(modeBuf, "client")) { 1043 | *mode = MODE_CLIENT; 1044 | ret = true; 1045 | } 1046 | } 1047 | else { 1048 | if(strstr(modeBuf, "1")) { 1049 | *mode = MODE_SERVER; 1050 | ret = true; 1051 | 1052 | } 1053 | else if(strstr(modeBuf, "2")) { 1054 | *mode = MODE_CLIENT; 1055 | ret = true; 1056 | } 1057 | } 1058 | 1059 | end: 1060 | return ret; 1061 | } 1062 | 1063 | bool AtDrv::setMode(uint8_t sock, int mode, long timeout) 1064 | { 1065 | bool ret = false; 1066 | char modeBuf[MAX_TEMP_BUF_SIZE]; 1067 | 1068 | if(mode <= MODE_NONE || mode > MODE_SERVER) { 1069 | INFO1("Invalid mode"); 1070 | goto end; 1071 | } 1072 | 1073 | if(mode == MODE_SERVER) { 1074 | if(sock == 0) 1075 | sprintf(modeBuf, at_mode[sock], "server"); 1076 | else 1077 | sprintf(modeBuf, at_mode[sock], "1"); 1078 | } 1079 | else { 1080 | if(sock == 0) 1081 | sprintf(modeBuf, at_mode[sock], "client"); 1082 | else 1083 | sprintf(modeBuf, at_mode[sock], "2"); 1084 | } 1085 | 1086 | clearSerialRxData(); 1087 | INFO1(modeBuf); 1088 | serialPort[0]->print(modeBuf); 1089 | serialPort[0]->flush(); 1090 | serialPort[0]->setTimeout(timeout); 1091 | if(!serialPort[0]->find(modeBuf) || !serialPort[0]->find(at_ok)) { 1092 | INFO1("Fail to set mode"); 1093 | goto end; 1094 | } 1095 | 1096 | ret = true; 1097 | end: 1098 | return ret; 1099 | } 1100 | 1101 | bool AtDrv::getProtocol(uint8_t sock, uint8_t *protocol, long timeout) 1102 | { 1103 | bool ret = false; 1104 | int bytes; 1105 | char protModeBuf[MAX_TEMP_BUF_SIZE]; 1106 | 1107 | sprintf(protModeBuf, at_remotepro[sock], "?"); 1108 | 1109 | clearSerialRxData(); 1110 | INFO1(protModeBuf); 1111 | serialPort[0]->print(protModeBuf); 1112 | serialPort[0]->flush(); 1113 | serialPort[0]->setTimeout(timeout); 1114 | if(!serialPort[0]->find(protModeBuf)) { 1115 | INFO1("Fail to get protocol"); 1116 | goto end; 1117 | } 1118 | 1119 | bytes = serialPort[0]->readBytes(protModeBuf, MAX_TEMP_BUF_SIZE); 1120 | 1121 | if(bytes >= MAX_TEMP_BUF_SIZE) { 1122 | INFO1("Buffer is not enough"); 1123 | goto end; 1124 | } 1125 | 1126 | protModeBuf[bytes] = NULL; 1127 | 1128 | if(sock == 0) { 1129 | if(strstr(protModeBuf, "tcp")) { 1130 | *protocol = PROTO_MODE_TCP; 1131 | ret = true; 1132 | 1133 | } 1134 | else if(strstr(protModeBuf, "udp")) { 1135 | *protocol = PROTO_MODE_UDP; 1136 | ret = true; 1137 | } 1138 | } 1139 | else { 1140 | if(strstr(protModeBuf, "1")) { 1141 | *protocol = PROTO_MODE_TCP; 1142 | ret = true; 1143 | 1144 | } 1145 | else if(strstr(protModeBuf, "2")) { 1146 | *protocol = PROTO_MODE_UDP; 1147 | ret = true; 1148 | } 1149 | } 1150 | 1151 | end: 1152 | return ret; 1153 | } 1154 | 1155 | bool AtDrv::setProtocol(uint8_t sock, uint8_t protocol, long timeout) 1156 | { 1157 | bool ret = false; 1158 | char protModeBuf[MAX_TEMP_BUF_SIZE]; 1159 | 1160 | if(protocol != PROTO_MODE_TCP && protocol != PROTO_MODE_UDP) { 1161 | INFO1("Invalid protocol"); 1162 | goto end; 1163 | } 1164 | 1165 | if(protocol == PROTO_MODE_TCP) { 1166 | if(sock == 0) 1167 | sprintf(protModeBuf, at_remotepro[sock], "tcp"); 1168 | else 1169 | sprintf(protModeBuf, at_remotepro[sock], "1"); 1170 | } 1171 | else { 1172 | if(sock == 0) 1173 | sprintf(protModeBuf, at_remotepro[sock], "udp"); 1174 | else 1175 | sprintf(protModeBuf, at_remotepro[sock], "2"); 1176 | } 1177 | clearSerialRxData(); 1178 | INFO1(protModeBuf); 1179 | serialPort[0]->print(protModeBuf); 1180 | serialPort[0]->flush(); 1181 | serialPort[0]->setTimeout(timeout); 1182 | if(!serialPort[0]->find(protModeBuf) || !serialPort[0]->find(at_ok)) { 1183 | INFO1("Fail to set protocol"); 1184 | goto end; 1185 | } 1186 | 1187 | ret = true; 1188 | end: 1189 | return ret; 1190 | } 1191 | 1192 | bool AtDrv::setLocalPort(uint8_t sock, uint16_t port, long timeout) 1193 | { 1194 | bool ret = false; 1195 | char localPortBuf[MAX_TEMP_BUF_SIZE]; 1196 | char portBuf[MAX_TEMP_BUF_SIZE]; 1197 | 1198 | sprintf(portBuf, "%u", port); 1199 | sprintf(localPortBuf, at_CLport[sock], portBuf); 1200 | 1201 | clearSerialRxData(); 1202 | INFO1(localPortBuf); 1203 | serialPort[0]->print(localPortBuf); 1204 | serialPort[0]->flush(); 1205 | serialPort[0]->setTimeout(timeout); 1206 | if(!serialPort[0]->find(localPortBuf) || !serialPort[0]->find(at_ok)) { 1207 | INFO1("Fail to set local port"); 1208 | goto end; 1209 | } 1210 | 1211 | ret = true; 1212 | end: 1213 | return ret; 1214 | } 1215 | 1216 | bool AtDrv::setPort(uint8_t sock, uint16_t port, long timeout) 1217 | { 1218 | bool ret = false; 1219 | char remotePortBuf[MAX_TEMP_BUF_SIZE]; 1220 | char portBuf[MAX_TEMP_BUF_SIZE]; 1221 | 1222 | sprintf(portBuf, "%u", port); 1223 | sprintf(remotePortBuf, at_remoteport[sock], portBuf); 1224 | 1225 | clearSerialRxData(); 1226 | INFO1(remotePortBuf); 1227 | serialPort[0]->print(remotePortBuf); 1228 | serialPort[0]->flush(); 1229 | serialPort[0]->setTimeout(timeout); 1230 | if(!serialPort[0]->find(remotePortBuf) || !serialPort[0]->find(at_ok)) { 1231 | INFO1("Fail to set port"); 1232 | goto end; 1233 | } 1234 | 1235 | ret = true; 1236 | end: 1237 | return ret; 1238 | } 1239 | 1240 | bool AtDrv::setRemoteIp(uint8_t sock, uint32_t ip, long timeout) 1241 | { 1242 | bool ret = false; 1243 | char remoteIpBuf[MAX_TEMP_BUF_SIZE]; 1244 | char ipBuf[MAX_TEMP_BUF_SIZE]; 1245 | uint8_t *pIp = (uint8_t*) &ip; 1246 | sprintf(ipBuf, "%u.%u.%u.%u", pIp[0], pIp[1], pIp[2], pIp[3]); 1247 | sprintf(remoteIpBuf, at_remoteip[sock], ipBuf); 1248 | 1249 | clearSerialRxData(); 1250 | INFO1(remoteIpBuf); 1251 | serialPort[0]->print(remoteIpBuf); 1252 | serialPort[0]->flush(); 1253 | serialPort[0]->setTimeout(timeout); 1254 | if(!serialPort[0]->find(remoteIpBuf) || !serialPort[0]->find(at_ok)) { 1255 | INFO1("Fail to set port"); 1256 | goto end; 1257 | } 1258 | 1259 | ret = true; 1260 | end: 1261 | return ret; 1262 | } 1263 | 1264 | bool AtDrv::getRemoteHost(uint8_t sock, char *host, long timeout) 1265 | { 1266 | bool ret = false; 1267 | int bytes; 1268 | char remoteHostBuf[MAX_HOST_NAME_BUF_SIZE]; 1269 | char *tok; 1270 | 1271 | sprintf(remoteHostBuf, at_remoteip[sock], "?"); 1272 | 1273 | clearSerialRxData(); 1274 | INFO1(remoteHostBuf); 1275 | serialPort[0]->print(remoteHostBuf); 1276 | serialPort[0]->flush(); 1277 | serialPort[0]->setTimeout(timeout); 1278 | if(!serialPort[0]->find(remoteHostBuf)) { 1279 | INFO1("Fail to set port"); 1280 | goto end; 1281 | } 1282 | 1283 | bytes = serialPort[0]->readBytes(remoteHostBuf, MAX_HOST_NAME_BUF_SIZE); 1284 | 1285 | if(bytes >= MAX_HOST_NAME_BUF_SIZE) { 1286 | INFO1("Buffer is not enough"); 1287 | goto end; 1288 | } 1289 | 1290 | remoteHostBuf[bytes] = NULL; 1291 | 1292 | tok = strtok(remoteHostBuf, " \r\n"); 1293 | if(tok) { 1294 | ret = true; 1295 | strcpy(host, tok); 1296 | } 1297 | end: 1298 | return ret; 1299 | } 1300 | 1301 | bool AtDrv::setRemoteHost(uint8_t sock, const char *host, long timeout) 1302 | { 1303 | bool ret = false; 1304 | char remoteHostBuf[MAX_HOST_NAME_BUF_SIZE]; 1305 | 1306 | sprintf(remoteHostBuf, at_remoteip[sock], host); 1307 | 1308 | clearSerialRxData(); 1309 | INFO1(remoteHostBuf); 1310 | serialPort[0]->print(remoteHostBuf); 1311 | serialPort[0]->flush(); 1312 | serialPort[0]->setTimeout(timeout); 1313 | if(!serialPort[0]->find(remoteHostBuf) || !serialPort[0]->find(at_ok)) { 1314 | INFO1("Fail to set port"); 1315 | goto end; 1316 | } 1317 | 1318 | ret = true; 1319 | end: 1320 | return ret; 1321 | } 1322 | 1323 | void AtDrv::startServer(uint8_t sock, uint16_t port, uint8_t protMode) 1324 | { 1325 | bool needReConn = false; 1326 | int curMode; 1327 | uint8_t curProtocol; 1328 | uint16_t curPort; 1329 | uint32_t curTimeout; 1330 | 1331 | if(!isAtMode()) { 1332 | if(!switchToAtMode()) { 1333 | INFO1("Can't switch to at mode"); 1334 | goto end; 1335 | } 1336 | } 1337 | 1338 | if(!getMode(sock, &curMode) || curMode != MODE_SERVER) { 1339 | needReConn = true; 1340 | INFO1("curMode != MODE_SERVER"); 1341 | if(!setMode(sock, MODE_SERVER)) { 1342 | INFO1("Can't set mode"); 1343 | goto end; 1344 | } 1345 | } 1346 | 1347 | if(!getProtocol(sock, &curProtocol) || curProtocol != protMode) { 1348 | needReConn = true; 1349 | INFO1("curProtocol != protMode"); 1350 | if(!setProtocol(sock, protMode)) { 1351 | INFO1("Can't set protocol"); 1352 | goto end; 1353 | } 1354 | } 1355 | 1356 | if(!getRemotePort(sock, &curPort) || curPort != port) { 1357 | needReConn = true; 1358 | INFO1("curPort != port"); 1359 | if(!setPort(sock, port)) { 1360 | INFO1("Can't set port"); 1361 | goto end; 1362 | } 1363 | } 1364 | 1365 | if(!getNetworkTimeout(sock, &curTimeout) || curTimeout != 0) { 1366 | needReConn = true; 1367 | INFO1("curTimeout != 0"); 1368 | if(!setNetworkTimeout(sock, 0)) { 1369 | INFO1("Can't set timeout"); 1370 | goto end; 1371 | } 1372 | } 1373 | 1374 | if(needReConn) { 1375 | if(!reConnect()) { 1376 | INFO1("Can't reconnect"); 1377 | goto end; 1378 | } 1379 | } 1380 | 1381 | sockPort[sock] = port; 1382 | sockConnected[sock] = true; 1383 | 1384 | end: 1385 | return; 1386 | } 1387 | 1388 | void AtDrv::startClient(uint8_t sock, uint32_t ipAddress, uint16_t port, uint8_t protMode) 1389 | { 1390 | // if we enable CHECK_TCP_STATE feature, always call reConnect(), or we won't get right 1391 | // tcp port status, since we disable tcp auto reconnect. 1392 | #ifndef CHECK_TCP_STATE 1393 | bool needReConn = false; 1394 | #else 1395 | bool needReConn = true; 1396 | #endif 1397 | int curMode; 1398 | uint32_t curIp; 1399 | uint8_t curProtocol; 1400 | uint16_t curPort; 1401 | uint16_t curLocalPort; 1402 | uint32_t curTimeout; 1403 | bool curTcpAuto; 1404 | 1405 | // clear uart buffer first 1406 | stopClient(sock); 1407 | 1408 | if(!isAtMode()) { 1409 | if(!switchToAtMode()) { 1410 | INFO1("Can't switch to at mode"); 1411 | goto end; 1412 | } 1413 | } 1414 | 1415 | if(!getMode(sock, &curMode) || curMode != MODE_CLIENT) { 1416 | needReConn = true; 1417 | INFO1("curMode != MODE_CLIENT"); 1418 | if(!setMode(sock, MODE_CLIENT)) { 1419 | INFO1("Can't set mode"); 1420 | goto end; 1421 | } 1422 | } 1423 | 1424 | if(!getRemoteIp(sock, (uint8_t *)&curIp) || curIp != ipAddress) { 1425 | needReConn = true; 1426 | INFO1("curIp != ipAddress"); 1427 | if(!setRemoteIp(sock, ipAddress)) { 1428 | INFO1("Can't set ip"); 1429 | goto end; 1430 | } 1431 | } 1432 | 1433 | if(!getProtocol(sock, &curProtocol) || curProtocol != protMode) { 1434 | needReConn = true; 1435 | INFO1("curProtocol != protMode"); 1436 | if(!setProtocol(sock, protMode)) { 1437 | INFO1("Can't set protocol"); 1438 | goto end; 1439 | } 1440 | } 1441 | 1442 | if(!getRemotePort(sock, &curPort) || curPort != port) { 1443 | needReConn = true; 1444 | INFO1("curPort != port"); 1445 | if(!setPort(sock, port)) { 1446 | INFO1("Can't set port"); 1447 | goto end; 1448 | } 1449 | } 1450 | 1451 | if(!getTcpAuto(sock, &curTcpAuto) || curTcpAuto != false) { 1452 | needReConn = true; 1453 | INFO1("curTcpAuto != false"); 1454 | if(!setTcpAuto(sock, false)) { 1455 | INFO1("Can't set tcp auto"); 1456 | goto end; 1457 | } 1458 | } 1459 | 1460 | if(!getLocalPort(sock, &curLocalPort) || curLocalPort != localSockPort[sock]) { 1461 | needReConn = true; 1462 | INFO1("curLocalPort != port"); 1463 | if(!setLocalPort(sock, localSockPort[sock])) { 1464 | INFO1("Can't set port"); 1465 | goto end; 1466 | } 1467 | } 1468 | 1469 | if(needReConn) { 1470 | if(!reConnect()) { 1471 | INFO1("Can't reconnect"); 1472 | goto end; 1473 | } 1474 | } 1475 | 1476 | sockPort[sock] = localSockPort[sock]; 1477 | sockConnected[sock] = true; 1478 | 1479 | end: 1480 | return; 1481 | } 1482 | 1483 | void AtDrv::startClient(uint8_t sock, const char *host, uint16_t port, uint8_t protMode) 1484 | { 1485 | // if we enable CHECK_TCP_STATE feature, always call reConnect(), or we won't get right 1486 | // tcp port status, since we disable tcp auto reconnect. 1487 | #ifndef CHECK_TCP_STATE 1488 | bool needReConn = false; 1489 | #else 1490 | bool needReConn = true; 1491 | #endif 1492 | int curMode; 1493 | char curHostBuf[MAX_HOST_NAME_BUF_SIZE]; 1494 | uint8_t curProtocol; 1495 | uint16_t curPort; 1496 | uint16_t curLocalPort; 1497 | uint32_t curTimeout; 1498 | bool curTcpAuto; 1499 | 1500 | // clear uart buffer first 1501 | stopClient(sock); 1502 | 1503 | if(!isAtMode()) { 1504 | if(!switchToAtMode()) { 1505 | INFO1("Can't switch to at mode"); 1506 | goto end; 1507 | } 1508 | } 1509 | 1510 | if(!getMode(sock, &curMode) || curMode != MODE_CLIENT) { 1511 | needReConn = true; 1512 | INFO1("curMode != MODE_CLIENT"); 1513 | if(!setMode(sock, MODE_CLIENT)) { 1514 | INFO1("Can't set mode"); 1515 | goto end; 1516 | } 1517 | } 1518 | 1519 | if(!getRemoteHost(sock, curHostBuf) || (strcmp(curHostBuf, host) != 0)) { 1520 | needReConn = true; 1521 | INFO1("curHostBuf != host"); 1522 | if(!setRemoteHost(sock, host)) { 1523 | INFO1("Can't set host"); 1524 | goto end; 1525 | } 1526 | } 1527 | 1528 | if(!getProtocol(sock, &curProtocol) || curProtocol != protMode) { 1529 | needReConn = true; 1530 | INFO1("curProtocol != protMode"); 1531 | if(!setProtocol(sock, protMode)) { 1532 | INFO1("Can't set protocol"); 1533 | goto end; 1534 | } 1535 | } 1536 | 1537 | if(!getRemotePort(sock, &curPort) || curPort != port) { 1538 | needReConn = true; 1539 | INFO1("curPort != port"); 1540 | if(!setPort(sock, port)) { 1541 | INFO1("Can't set port"); 1542 | goto end; 1543 | } 1544 | } 1545 | 1546 | if(!getTcpAuto(sock, &curTcpAuto) || curTcpAuto != false) { 1547 | needReConn = true; 1548 | INFO1("curTcpAuto != false"); 1549 | if(!setTcpAuto(sock, false)) { 1550 | INFO1("Can't set tcp auto"); 1551 | goto end; 1552 | } 1553 | } 1554 | 1555 | if(!getLocalPort(sock, &curLocalPort) || curLocalPort != localSockPort[sock]) { 1556 | needReConn = true; 1557 | INFO1("curLocalPort != port"); 1558 | if(!setLocalPort(sock, localSockPort[sock])) { 1559 | INFO1("Can't set port"); 1560 | goto end; 1561 | } 1562 | } 1563 | 1564 | if(needReConn) { 1565 | if(!reConnect()) { 1566 | INFO1("Can't reconnect"); 1567 | goto end; 1568 | } 1569 | } 1570 | 1571 | sockPort[sock] = localSockPort[sock]; 1572 | sockConnected[sock] = true; 1573 | 1574 | end: 1575 | return; 1576 | } 1577 | 1578 | uint16_t AtDrv::availData(uint8_t sock) 1579 | { 1580 | uint16_t len = 0; 1581 | 1582 | // sock1 (second uart port) is always in data mode, so don't need to switch mode 1583 | if(sock == 0 && isAtMode()) { 1584 | if(!switchToDataMode()) { 1585 | INFO1("Can't switch to data mode"); 1586 | goto end; 1587 | } 1588 | } 1589 | 1590 | // sock0's available data len should plus the data in sock0DataQueue 1591 | if(sock == 0) 1592 | len = sock0DataQueue.count(); 1593 | 1594 | len += serialPort[sock]->available(); 1595 | end: 1596 | return len; 1597 | } 1598 | 1599 | int AtDrv::peek(uint8_t sock) 1600 | { 1601 | int c = -1; 1602 | 1603 | // sock1 (second uart port) is always in data mode, so don't need to switch mode 1604 | if(sock == 0 && isAtMode()) { 1605 | if(!switchToDataMode()) { 1606 | INFO1("Can't switch to data mode"); 1607 | goto end; 1608 | } 1609 | } 1610 | 1611 | // if sock0 && sock0DataQueue has data, then peek data in sock0DataQueue 1612 | if(sock == 0 && !sock0DataQueue.isEmpty()) 1613 | c = sock0DataQueue.peek(); 1614 | else 1615 | c = serialPort[sock]->peek(); 1616 | end: 1617 | return c; 1618 | } 1619 | 1620 | int AtDrv::read(uint8_t sock) 1621 | { 1622 | int c = -1; 1623 | 1624 | // sock1 (second uart port) is always in data mode, so don't need to switch mode 1625 | if(sock == 0 && isAtMode()) { 1626 | if(!switchToDataMode()) { 1627 | INFO1("Can't switch to data mode"); 1628 | goto end; 1629 | } 1630 | } 1631 | 1632 | // if sock0 && sock0DataQueue has data, then read data in sock0DataQueue 1633 | if(sock == 0 && !sock0DataQueue.isEmpty()) 1634 | c = sock0DataQueue.pop(); 1635 | else 1636 | c = serialPort[sock]->read(); 1637 | end: 1638 | return c; 1639 | } 1640 | 1641 | uint16_t AtDrv::readBytes(uint8_t sock, uint8_t *_data, uint16_t *_dataLen) 1642 | { 1643 | uint16_t len = 0; 1644 | 1645 | // sock1 (second uart port) is always in data mode, so don't need to switch mode 1646 | if(sock == 0 && isAtMode()) { 1647 | if(!switchToDataMode()) { 1648 | INFO1("Can't switch to data mode"); 1649 | goto end; 1650 | } 1651 | } 1652 | 1653 | // if sock0 && sock0DataQueue has data, then read data in sock0DataQueue first 1654 | if(sock == 0) { 1655 | while(!sock0DataQueue.isEmpty()) { 1656 | _data[len++] = sock0DataQueue.pop(); 1657 | // full? then exit 1658 | if(len == *_dataLen) 1659 | goto end; 1660 | } 1661 | // substrate data length we've filled 1662 | *_dataLen -= len; 1663 | } 1664 | 1665 | len += serialPort[sock]->readBytes((char *)_data+len, *_dataLen); 1666 | *_dataLen = len; 1667 | end: 1668 | return len; 1669 | } 1670 | 1671 | uint16_t AtDrv::write(uint8_t sock, const uint8_t *data, uint16_t _len) 1672 | { 1673 | uint16_t len = 0; 1674 | 1675 | // sock1 (second uart port) is always in data mode, so don't need to switch mode 1676 | if(sock == 0 && isAtMode()) { 1677 | if(!switchToDataMode()) { 1678 | INFO1("Can't switch to data mode"); 1679 | goto end; 1680 | } 1681 | } 1682 | 1683 | len = serialPort[sock]->write(data, _len); 1684 | end: 1685 | return len; 1686 | } 1687 | 1688 | uint8_t AtDrv::portStateMapping(LinuxTcpState linuxPortState) 1689 | { 1690 | switch (linuxPortState) { 1691 | case TCP_ESTABLISHED: 1692 | return ESTABLISHED; 1693 | 1694 | case TCP_SYN_SENT: 1695 | return SYN_SENT; 1696 | 1697 | case TCP_SYN_RECV: 1698 | return SYN_RCVD; 1699 | 1700 | case TCP_FIN_WAIT1: 1701 | return FIN_WAIT_1; 1702 | 1703 | case TCP_FIN_WAIT2: 1704 | return FIN_WAIT_2; 1705 | 1706 | case TCP_TIME_WAIT: 1707 | return TIME_WAIT; 1708 | 1709 | case TCP_CLOSE: 1710 | return CLOSED; 1711 | 1712 | case TCP_CLOSE_WAIT: 1713 | return CLOSE_WAIT; 1714 | 1715 | case TCP_LAST_ACK: 1716 | return LAST_ACK; 1717 | 1718 | case TCP_LISTEN: 1719 | return LISTEN; 1720 | 1721 | case TCP_CLOSING: 1722 | return CLOSING; 1723 | 1724 | default: 1725 | return CLOSED; 1726 | } 1727 | } 1728 | 1729 | uint8_t AtDrv::getClientState(uint8_t sock, long timeout) 1730 | { 1731 | #ifndef CHECK_TCP_STATE 1732 | // Since RM04 can't get current connection status, we always return ESTABLISHED 1733 | sockConnected[sock] = true; 1734 | return ESTABLISHED; 1735 | #else 1736 | // Try to use at+excxxx to get & parse tcp port state 1737 | bool found = false; 1738 | uint8_t ret = CLOSED; 1739 | int bytes; 1740 | LinuxTcpState portState; 1741 | int start; 1742 | char lineBuf[MAX_LINE_BUF_SIZE]; 1743 | char cmdBuf[MAX_TEMP_BUF_SIZE]; 1744 | char *token; 1745 | 1746 | if(!isAtMode()) { 1747 | if(!switchToAtMode()) { 1748 | INFO1("Can't switch to at mode"); 1749 | goto end; 1750 | } 1751 | } 1752 | 1753 | clearSerialRxData(); 1754 | sprintf(cmdBuf, at_tcp_port_stat, sockPort[sock]); 1755 | INFO1(cmdBuf); 1756 | serialPort[0]->print(cmdBuf); 1757 | serialPort[0]->print("\r\r"); 1758 | serialPort[0]->flush(); 1759 | serialPort[0]->setTimeout(timeout); 1760 | 1761 | // skip cmd response 1762 | serialPort[0]->find(cmdBuf); 1763 | 1764 | for(int i=0;;i++) { 1765 | 1766 | found = serialPort[0]->find(":"); 1767 | 1768 | if(found) 1769 | { 1770 | bytes = serialPort[0]->readBytesUntil('\n', lineBuf, MAX_LINE_BUF_SIZE); 1771 | if(bytes >= MAX_LINE_BUF_SIZE) { 1772 | INFO1("Buffer is not enough"); 1773 | goto end; 1774 | } 1775 | lineBuf[bytes] = NULL; 1776 | //INFO1(lineBuf); 1777 | 1778 | token = strtok(lineBuf, " :\r\n"); 1779 | token = strtok(NULL, " :\r\n"); 1780 | if(token == NULL) { 1781 | INFO1("failed to parse tcp info"); 1782 | goto end; 1783 | } 1784 | //INFO1("TCP port: "); 1785 | //INFO1(token); 1786 | 1787 | if(strtol(token, NULL, 16) == sockPort[sock]) { 1788 | //INFO1("Found port"); 1789 | token = strtok(NULL, " :\r\n"); 1790 | token = strtok(NULL, " :\r\n"); 1791 | token = strtok(NULL, " :\r\n"); 1792 | if(token == NULL) { 1793 | //INFO1("failed to parse tcp info"); 1794 | goto end; 1795 | } 1796 | //INFO1("Port state: "); 1797 | //INFO1(token); 1798 | portState = (LinuxTcpState) strtol(token, NULL, 16); 1799 | ret = portStateMapping(portState); 1800 | // if port state is ESTABLISHED, return immediately. otherwise, keep parsing 1801 | if(ret == ESTABLISHED) { 1802 | sockConnected[sock] = true; 1803 | goto end; 1804 | } 1805 | } 1806 | } 1807 | else { 1808 | INFO1("Not Found"); 1809 | } 1810 | 1811 | serialPort[0]->setTimeout(SERIAL_TIMEOUT); 1812 | 1813 | if(!serialPort[0]->available()) { 1814 | INFO1("No data"); 1815 | break; 1816 | } 1817 | } 1818 | 1819 | 1820 | end: 1821 | clearSerialRxData(); 1822 | return ret; 1823 | #endif 1824 | } 1825 | 1826 | void AtDrv::stopClient(uint8_t sock) 1827 | { 1828 | if(sock == 0 && isAtMode()) { 1829 | if(!switchToDataMode()) { 1830 | INFO1("Can't switch to data mode"); 1831 | goto end; 1832 | } 1833 | } 1834 | 1835 | if(sock == 0) { 1836 | while(!sock0DataQueue.isEmpty()) 1837 | sock0DataQueue.pop(); 1838 | } 1839 | 1840 | // clear uart buffer, since we won't use it 1841 | while(serialPort[sock]->available()) 1842 | serialPort[sock]->read(); 1843 | 1844 | end: 1845 | sockConnected[sock] = false; 1846 | return; 1847 | } 1848 | 1849 | bool AtDrv::disconnect() 1850 | { 1851 | bool ret = false; 1852 | 1853 | if(!isAtMode()) { 1854 | if(!switchToAtMode()) { 1855 | INFO1("Can't switch to at mode"); 1856 | goto end; 1857 | } 1858 | } 1859 | 1860 | // set netmode as eth mode will disable wifi 1861 | if(!setNetMode(NET_MODE_ETH)) 1862 | goto end; 1863 | 1864 | netCommit(); 1865 | 1866 | ret = true; 1867 | end: 1868 | return ret; 1869 | } 1870 | 1871 | uint8_t AtDrv::getScanNetworks(char _networkSsid[][WL_SSID_MAX_LENGTH+1], int32_t _networkRssi[], uint8_t _networkEncr[], uint8_t maxItems, long timeout) 1872 | { 1873 | uint8_t numItems = 0; 1874 | int bytes; 1875 | char lineBuf[MAX_LINE_BUF_SIZE]; 1876 | 1877 | if(!isAtMode()) { 1878 | if(!switchToAtMode()) { 1879 | INFO1("Can't switch to at mode"); 1880 | goto end; 1881 | } 1882 | } 1883 | 1884 | clearSerialRxData(); 1885 | INFO1(at_wifi_Scan); 1886 | serialPort[0]->print(at_wifi_Scan); 1887 | serialPort[0]->flush(); 1888 | serialPort[0]->setTimeout(timeout); 1889 | 1890 | // skip cmd response 1891 | serialPort[0]->find(at_wifi_Scan); 1892 | serialPort[0]->readBytesUntil('\n', lineBuf, MAX_LINE_BUF_SIZE); 1893 | 1894 | // find item 1895 | do { 1896 | bytes = serialPort[0]->readBytesUntil('\n', lineBuf, MAX_LINE_BUF_SIZE); 1897 | if(bytes >= MAX_LINE_BUF_SIZE) { 1898 | INFO1("Buffer is not enough"); 1899 | goto end; 1900 | } 1901 | else if(bytes == 0) { 1902 | INFO1("No more items"); 1903 | goto end; 1904 | } 1905 | lineBuf[bytes] = NULL; 1906 | // a valid item line should be channel num (a number) and contains 100 characters above 1907 | if(lineBuf[0] >= '0' && lineBuf[1] <= '9' && bytes > 100) { 1908 | INFO1("Found a item"); 1909 | // parse ssid 1910 | // ssid should starts at lineBuf[4] 1911 | if(lineBuf[4] == ' ') { 1912 | INFO1("A hidden ssid, skip"); 1913 | continue; 1914 | } 1915 | memcpy(_networkSsid[numItems], &lineBuf[4], WL_SSID_MAX_LENGTH); 1916 | // truncate trail spaces of ssid 1917 | int i = WL_SSID_MAX_LENGTH-1; 1918 | _networkSsid[numItems][WL_SSID_MAX_LENGTH] = NULL; 1919 | while(_networkSsid[numItems][i--] == ' ' && i > 0); 1920 | 1921 | _networkSsid[numItems][i+2] = NULL; 1922 | INFO1(_networkSsid[numItems]); 1923 | 1924 | // parse enc type 1925 | // security type should starts at lineBuf[57] and ends at lineBuf[78] 1926 | char *enc = &lineBuf[57]; 1927 | lineBuf[79] = NULL; 1928 | if(strstr(enc, "/TKIPAES") != NULL) { 1929 | INFO1("AUTO"); 1930 | _networkEncr[numItems] = ENC_TYPE_AUTO; 1931 | } 1932 | else if(strstr(enc, "NONE") != NULL) { 1933 | INFO1("NONE"); 1934 | _networkEncr[numItems] = ENC_TYPE_NONE; 1935 | } 1936 | else if(strstr(enc, "/AES") != NULL) { 1937 | INFO1("AES"); 1938 | _networkEncr[numItems] = ENC_TYPE_CCMP; 1939 | } 1940 | else if(strstr(enc, "/TKIP") != NULL) { 1941 | INFO1("TKIP"); 1942 | _networkEncr[numItems] = ENC_TYPE_TKIP; 1943 | } 1944 | else if(strstr(enc, "WEP") != NULL) { 1945 | INFO1("WEP"); 1946 | _networkEncr[numItems] = ENC_TYPE_WEP; 1947 | } 1948 | else { 1949 | INFO1("Unknow, treat as error"); 1950 | continue; 1951 | } 1952 | 1953 | // parse signal strength 1954 | // signal strength should starts at lineBuf[80] and ends at lineBuf[82] 1955 | char *rssi = &lineBuf[80]; 1956 | lineBuf[83] = NULL; 1957 | // this is link qualit value (0~100) 1958 | _networkRssi[numItems] = strtoul(rssi, NULL, 10); 1959 | // convert link quality to dbm 1960 | _networkRssi[numItems] = (_networkRssi[numItems]/2) - 100; 1961 | 1962 | numItems++; 1963 | } 1964 | }while(numItems < maxItems); 1965 | 1966 | end: 1967 | clearSerialRxData(); 1968 | return numItems; 1969 | } 1970 | 1971 | void AtDrv::getCurrentSSID(char _ssid[], long timeout) 1972 | { 1973 | int bytes; 1974 | char buf[MAX_TEMP_BUF_SIZE]; 1975 | 1976 | if(!isAtMode()) { 1977 | if(!switchToAtMode()) { 1978 | INFO1("Can't switch to at mode"); 1979 | goto end; 1980 | } 1981 | } 1982 | 1983 | clearSerialRxData(); 1984 | INFO1(at_get_ssid); 1985 | serialPort[0]->print(at_get_ssid); 1986 | serialPort[0]->print("\r\r"); 1987 | serialPort[0]->flush(); 1988 | serialPort[0]->setTimeout(timeout); 1989 | 1990 | // skip cmd response 1991 | if(!serialPort[0]->find(at_get_ssid)) { 1992 | INFO1("fail to get ssid"); 1993 | _ssid[0] = NULL; 1994 | goto end; 1995 | } 1996 | 1997 | bytes = serialPort[0]->readBytesUntil('\n', buf, MAX_TEMP_BUF_SIZE); 1998 | if(bytes >= MAX_TEMP_BUF_SIZE || bytes > WL_SSID_MAX_LENGTH) { 1999 | INFO1("Buffer is not enough"); 2000 | _ssid[0] = NULL; 2001 | goto end; 2002 | } 2003 | 2004 | buf[bytes] = NULL; 2005 | 2006 | strncpy(_ssid, buf, WL_SSID_MAX_LENGTH+1); 2007 | end: 2008 | clearSerialRxData(); 2009 | return; 2010 | } 2011 | 2012 | void AtDrv::getCurrentBSSID(uint8_t _bssid[], long timeout) 2013 | { 2014 | int bytes; 2015 | int i = 0; 2016 | char *token; 2017 | char buf[MAX_TEMP_BUF_SIZE]; 2018 | 2019 | if(!isAtMode()) { 2020 | if(!switchToAtMode()) { 2021 | INFO1("Can't switch to at mode"); 2022 | goto end; 2023 | } 2024 | } 2025 | 2026 | clearSerialRxData(); 2027 | INFO1(at_get_bssid); 2028 | serialPort[0]->print(at_get_bssid); 2029 | serialPort[0]->print("\r\r"); 2030 | serialPort[0]->flush(); 2031 | serialPort[0]->setTimeout(timeout); 2032 | 2033 | // skip cmd response 2034 | if(!serialPort[0]->find(at_get_bssid)) { 2035 | INFO1("fail to get bssid"); 2036 | memset(_bssid, 0, WL_MAC_ADDR_LENGTH); 2037 | goto end; 2038 | } 2039 | 2040 | bytes = serialPort[0]->readBytes(buf, MAX_TEMP_BUF_SIZE); 2041 | 2042 | if(bytes >= MAX_TEMP_BUF_SIZE) { 2043 | INFO1("Buffer is not enough"); 2044 | memset(_bssid, 0, WL_MAC_ADDR_LENGTH); 2045 | goto end; 2046 | } 2047 | 2048 | buf[bytes] = NULL; 2049 | 2050 | token = strtok(buf, " :"); 2051 | 2052 | while(token != NULL && i < WL_MAC_ADDR_LENGTH) { 2053 | _bssid[WL_MAC_ADDR_LENGTH-1-i] = strtol(token, NULL, 16); 2054 | token = strtok(NULL, " :,\r\n"); 2055 | i++; 2056 | } 2057 | 2058 | if(i!=6) { 2059 | INFO1("Can't get valid MAC string"); 2060 | INFO1(buf); 2061 | memset(_bssid, 0, WL_MAC_ADDR_LENGTH); 2062 | goto end; 2063 | } 2064 | 2065 | end: 2066 | clearSerialRxData(); 2067 | return; 2068 | } 2069 | 2070 | int32_t AtDrv::getCurrentRSSI(long timeout) 2071 | { 2072 | int32_t rssi = 0; 2073 | clearSerialRxData(); 2074 | INFO1(at_get_rssi); 2075 | serialPort[0]->print(at_get_rssi); 2076 | serialPort[0]->print("\r\r"); 2077 | serialPort[0]->flush(); 2078 | serialPort[0]->setTimeout(timeout); 2079 | 2080 | // skip cmd response 2081 | if(!serialPort[0]->find(at_get_rssi)) { 2082 | INFO1("fail to get rssi"); 2083 | goto end; 2084 | } 2085 | 2086 | // this is link qualit value (0~100) 2087 | rssi = serialPort[0]->parseInt(); 2088 | // convert link quality to dbm 2089 | rssi = (rssi/2) - 100; 2090 | 2091 | INFO("RSSI: %ld dbm", rssi); 2092 | 2093 | end: 2094 | clearSerialRxData(); 2095 | return rssi; 2096 | } 2097 | 2098 | uint8_t AtDrv::getCurrentEncryptionType(long timeout) 2099 | { 2100 | uint8_t enc = 0; 2101 | int bytes; 2102 | char buf[MAX_TEMP_BUF_SIZE]; 2103 | 2104 | if(!isAtMode()) { 2105 | if(!switchToAtMode()) { 2106 | INFO1("Can't switch to at mode"); 2107 | goto end; 2108 | } 2109 | } 2110 | 2111 | clearSerialRxData(); 2112 | INFO1(at_get_enc); 2113 | serialPort[0]->print(at_get_enc); 2114 | serialPort[0]->print("\r\r"); 2115 | serialPort[0]->flush(); 2116 | serialPort[0]->setTimeout(timeout); 2117 | 2118 | // skip cmd response 2119 | if(!serialPort[0]->find(at_get_enc)) { 2120 | INFO1("fail to get enc type"); 2121 | goto end; 2122 | } 2123 | 2124 | bytes = serialPort[0]->readBytesUntil('\n', buf, MAX_TEMP_BUF_SIZE); 2125 | if(bytes >= MAX_TEMP_BUF_SIZE) { 2126 | INFO1("Buffer is not enough"); 2127 | goto end; 2128 | } 2129 | 2130 | buf[bytes] = NULL; 2131 | 2132 | if(strstr(buf, "/TKIPAES") != NULL) { 2133 | enc = ENC_TYPE_AUTO; 2134 | } 2135 | else if(strstr(buf, "NONE") != NULL) { 2136 | enc = ENC_TYPE_NONE; 2137 | } 2138 | else if(strstr(buf, "/AES") != NULL) { 2139 | enc = ENC_TYPE_CCMP; 2140 | } 2141 | else if(strstr(buf, "/TKIP") != NULL) { 2142 | enc = ENC_TYPE_TKIP; 2143 | } 2144 | else if(strstr(buf, "WEP") != NULL) { 2145 | enc = ENC_TYPE_WEP; 2146 | } 2147 | else { 2148 | INFO1("Unknow, treat as error"); 2149 | } 2150 | 2151 | end: 2152 | clearSerialRxData(); 2153 | return enc; 2154 | } 2155 | 2156 | void AtDrv::getFwVersion(char fwVersion[], uint8_t bufLength, long timeout) 2157 | { 2158 | int bytes; 2159 | 2160 | if(!isAtMode()) { 2161 | if(!switchToAtMode()) { 2162 | INFO1("Can't switch to at mode"); 2163 | goto end; 2164 | } 2165 | } 2166 | 2167 | clearSerialRxData(); 2168 | INFO1(at_ver); 2169 | serialPort[0]->print(at_ver); 2170 | serialPort[0]->flush(); 2171 | serialPort[0]->setTimeout(timeout); 2172 | 2173 | // skip cmd response and '\n' 2174 | if(!serialPort[0]->find(at_ver) || !serialPort[0]->find("\n")) { 2175 | INFO1("fail to get firmware version"); 2176 | goto end; 2177 | } 2178 | 2179 | bytes = serialPort[0]->readBytesUntil('\r', fwVersion, bufLength); 2180 | fwVersion[bytes] = NULL; 2181 | 2182 | end: 2183 | clearSerialRxData(); 2184 | return; 2185 | } 2186 | 2187 | uint8_t AtDrv::checkDataSent(uint8_t sock) 2188 | { 2189 | // Since RM04 can't check data sent status, jsut flush our UART buffer instead 2190 | serialPort[sock]->flush(); 2191 | return 1; 2192 | } 2193 | 2194 | AtDrv::AtDrv() 2195 | { 2196 | #ifdef USE_ESCAPE_PIN 2197 | // need change pin mode and output it to inactive state in the very beginning, or 2198 | // might put module in facotry rest mode 2199 | pinMode(ESCAPE_PIN, OUTPUT); 2200 | digitalWrite(ESCAPE_PIN, !ESCAPE_PIN_ACTIVE); 2201 | #endif 2202 | sock0DataQueue.setPrinter(Serial); 2203 | } 2204 | 2205 | AtDrv atDrv; 2206 | 2207 | HardwareSerial* AtDrv::serialPort[] = {&AT_DRV_SERIAL, &AT_DRV_SERIAL1}; 2208 | bool AtDrv::atMode = false; 2209 | uint16_t AtDrv::sockPort[2] = {0}; 2210 | QueueList AtDrv::sock0DataQueue; 2211 | bool AtDrv::sockConnected[2] = {false, false}; 2212 | --------------------------------------------------------------------------------