Convert the few remaining cr/lf files to use lf for eol. (#1316)
If you develop on windows and need cr/lf files, see this: https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration#_formatting_and_whitespace Git can handle this by auto-converting CRLF line endings into LF when you add a file to the index, and vice versa when it checks out code onto your filesystem. You can turn on this functionality with the core.autocrlf setting. If you're on a Windows machine, set it to true - this converts LF endings into CRLF when you check out code: $ git config --global core.autocrlf true
This commit is contained in:
parent
1da3138ed6
commit
c92b617397
2
.gitignore
vendored
2
.gitignore
vendored
@ -4,4 +4,4 @@ tools/esptool
|
||||
tools/esptool.exe
|
||||
tools/mkspiffs/mkspiffs
|
||||
tools/mkspiffs/mkspiffs.exe
|
||||
.DS_Store
|
||||
.DS_Store
|
||||
|
@ -1,110 +1,110 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "HardwareSerial.h"
|
||||
|
||||
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL)
|
||||
HardwareSerial Serial(0);
|
||||
#endif
|
||||
|
||||
HardwareSerial::HardwareSerial(int uart_nr) : _uart_nr(uart_nr), _uart(NULL) {}
|
||||
|
||||
void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, int8_t txPin, bool invert)
|
||||
{
|
||||
if(0 > _uart_nr || _uart_nr > 2) {
|
||||
log_e("Serial number is invalid, please use 0, 1 or 2");
|
||||
return;
|
||||
}
|
||||
if(_uart) {
|
||||
end();
|
||||
}
|
||||
if(_uart_nr == 0 && rxPin < 0 && txPin < 0) {
|
||||
rxPin = 3;
|
||||
txPin = 1;
|
||||
}
|
||||
if(_uart_nr == 1 && rxPin < 0 && txPin < 0) {
|
||||
rxPin = 9;
|
||||
txPin = 10;
|
||||
}
|
||||
if(_uart_nr == 2 && rxPin < 0 && txPin < 0) {
|
||||
rxPin = 16;
|
||||
txPin = 17;
|
||||
}
|
||||
_uart = uartBegin(_uart_nr, baud, config, rxPin, txPin, 256, invert);
|
||||
}
|
||||
|
||||
void HardwareSerial::end()
|
||||
{
|
||||
if(uartGetDebug() == _uart_nr) {
|
||||
uartSetDebug(0);
|
||||
}
|
||||
uartEnd(_uart);
|
||||
_uart = 0;
|
||||
}
|
||||
|
||||
void HardwareSerial::setDebugOutput(bool en)
|
||||
{
|
||||
if(_uart == 0) {
|
||||
return;
|
||||
}
|
||||
if(en) {
|
||||
uartSetDebug(_uart);
|
||||
} else {
|
||||
if(uartGetDebug() == _uart_nr) {
|
||||
uartSetDebug(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int HardwareSerial::available(void)
|
||||
{
|
||||
return uartAvailable(_uart);
|
||||
}
|
||||
int HardwareSerial::availableForWrite(void)
|
||||
{
|
||||
return uartAvailableForWrite(_uart);
|
||||
}
|
||||
|
||||
int HardwareSerial::peek(void)
|
||||
{
|
||||
if (available()) {
|
||||
return uartPeek(_uart);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int HardwareSerial::read(void)
|
||||
{
|
||||
if(available()) {
|
||||
return uartRead(_uart);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void HardwareSerial::flush()
|
||||
{
|
||||
uartFlush(_uart);
|
||||
}
|
||||
|
||||
size_t HardwareSerial::write(uint8_t c)
|
||||
{
|
||||
uartWrite(_uart, c);
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t HardwareSerial::write(const uint8_t *buffer, size_t size)
|
||||
{
|
||||
uartWriteBuf(_uart, buffer, size);
|
||||
return size;
|
||||
}
|
||||
uint32_t HardwareSerial::baudRate()
|
||||
|
||||
{
|
||||
return uartGetBaudRate(_uart);
|
||||
}
|
||||
HardwareSerial::operator bool() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "HardwareSerial.h"
|
||||
|
||||
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL)
|
||||
HardwareSerial Serial(0);
|
||||
#endif
|
||||
|
||||
HardwareSerial::HardwareSerial(int uart_nr) : _uart_nr(uart_nr), _uart(NULL) {}
|
||||
|
||||
void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, int8_t txPin, bool invert)
|
||||
{
|
||||
if(0 > _uart_nr || _uart_nr > 2) {
|
||||
log_e("Serial number is invalid, please use 0, 1 or 2");
|
||||
return;
|
||||
}
|
||||
if(_uart) {
|
||||
end();
|
||||
}
|
||||
if(_uart_nr == 0 && rxPin < 0 && txPin < 0) {
|
||||
rxPin = 3;
|
||||
txPin = 1;
|
||||
}
|
||||
if(_uart_nr == 1 && rxPin < 0 && txPin < 0) {
|
||||
rxPin = 9;
|
||||
txPin = 10;
|
||||
}
|
||||
if(_uart_nr == 2 && rxPin < 0 && txPin < 0) {
|
||||
rxPin = 16;
|
||||
txPin = 17;
|
||||
}
|
||||
_uart = uartBegin(_uart_nr, baud, config, rxPin, txPin, 256, invert);
|
||||
}
|
||||
|
||||
void HardwareSerial::end()
|
||||
{
|
||||
if(uartGetDebug() == _uart_nr) {
|
||||
uartSetDebug(0);
|
||||
}
|
||||
uartEnd(_uart);
|
||||
_uart = 0;
|
||||
}
|
||||
|
||||
void HardwareSerial::setDebugOutput(bool en)
|
||||
{
|
||||
if(_uart == 0) {
|
||||
return;
|
||||
}
|
||||
if(en) {
|
||||
uartSetDebug(_uart);
|
||||
} else {
|
||||
if(uartGetDebug() == _uart_nr) {
|
||||
uartSetDebug(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int HardwareSerial::available(void)
|
||||
{
|
||||
return uartAvailable(_uart);
|
||||
}
|
||||
int HardwareSerial::availableForWrite(void)
|
||||
{
|
||||
return uartAvailableForWrite(_uart);
|
||||
}
|
||||
|
||||
int HardwareSerial::peek(void)
|
||||
{
|
||||
if (available()) {
|
||||
return uartPeek(_uart);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int HardwareSerial::read(void)
|
||||
{
|
||||
if(available()) {
|
||||
return uartRead(_uart);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void HardwareSerial::flush()
|
||||
{
|
||||
uartFlush(_uart);
|
||||
}
|
||||
|
||||
size_t HardwareSerial::write(uint8_t c)
|
||||
{
|
||||
uartWrite(_uart, c);
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t HardwareSerial::write(const uint8_t *buffer, size_t size)
|
||||
{
|
||||
uartWriteBuf(_uart, buffer, size);
|
||||
return size;
|
||||
}
|
||||
uint32_t HardwareSerial::baudRate()
|
||||
|
||||
{
|
||||
return uartGetBaudRate(_uart);
|
||||
}
|
||||
HardwareSerial::operator bool() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -1,71 +1,71 @@
|
||||
/**
|
||||
StreamString.cpp
|
||||
|
||||
Copyright (c) 2015 Markus Sattler. All rights reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "StreamString.h"
|
||||
|
||||
size_t StreamString::write(const uint8_t *data, size_t size)
|
||||
{
|
||||
if(size && data) {
|
||||
if(reserve(length() + size + 1)) {
|
||||
memcpy((void *) (buffer + len), (const void *) data, size);
|
||||
len += size;
|
||||
*(buffer + len) = 0x00; // add null for string end
|
||||
return size;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t StreamString::write(uint8_t data)
|
||||
{
|
||||
return concat((char) data);
|
||||
}
|
||||
|
||||
int StreamString::available()
|
||||
{
|
||||
return length();
|
||||
}
|
||||
|
||||
int StreamString::read()
|
||||
{
|
||||
if(length()) {
|
||||
char c = charAt(0);
|
||||
remove(0, 1);
|
||||
return c;
|
||||
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int StreamString::peek()
|
||||
{
|
||||
if(length()) {
|
||||
char c = charAt(0);
|
||||
return c;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void StreamString::flush()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
StreamString.cpp
|
||||
|
||||
Copyright (c) 2015 Markus Sattler. All rights reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "StreamString.h"
|
||||
|
||||
size_t StreamString::write(const uint8_t *data, size_t size)
|
||||
{
|
||||
if(size && data) {
|
||||
if(reserve(length() + size + 1)) {
|
||||
memcpy((void *) (buffer + len), (const void *) data, size);
|
||||
len += size;
|
||||
*(buffer + len) = 0x00; // add null for string end
|
||||
return size;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t StreamString::write(uint8_t data)
|
||||
{
|
||||
return concat((char) data);
|
||||
}
|
||||
|
||||
int StreamString::available()
|
||||
{
|
||||
return length();
|
||||
}
|
||||
|
||||
int StreamString::read()
|
||||
{
|
||||
if(length()) {
|
||||
char c = charAt(0);
|
||||
remove(0, 1);
|
||||
return c;
|
||||
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int StreamString::peek()
|
||||
{
|
||||
if(length()) {
|
||||
char c = charAt(0);
|
||||
return c;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void StreamString::flush()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1,39 +1,39 @@
|
||||
/**
|
||||
StreamString.h
|
||||
|
||||
Copyright (c) 2015 Markus Sattler. All rights reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
#ifndef STREAMSTRING_H_
|
||||
#define STREAMSTRING_H_
|
||||
|
||||
|
||||
class StreamString: public Stream, public String
|
||||
{
|
||||
public:
|
||||
size_t write(const uint8_t *buffer, size_t size) override;
|
||||
size_t write(uint8_t data) override;
|
||||
|
||||
int available() override;
|
||||
int read() override;
|
||||
int peek() override;
|
||||
void flush() override;
|
||||
};
|
||||
|
||||
|
||||
#endif /* STREAMSTRING_H_ */
|
||||
/**
|
||||
StreamString.h
|
||||
|
||||
Copyright (c) 2015 Markus Sattler. All rights reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
#ifndef STREAMSTRING_H_
|
||||
#define STREAMSTRING_H_
|
||||
|
||||
|
||||
class StreamString: public Stream, public String
|
||||
{
|
||||
public:
|
||||
size_t write(const uint8_t *buffer, size_t size) override;
|
||||
size_t write(uint8_t data) override;
|
||||
|
||||
int available() override;
|
||||
int read() override;
|
||||
int peek() override;
|
||||
void flush() override;
|
||||
};
|
||||
|
||||
|
||||
#endif /* STREAMSTRING_H_ */
|
||||
|
@ -1,65 +1,65 @@
|
||||
/**
|
||||
* base64.cpp
|
||||
*
|
||||
* Created on: 09.12.2015
|
||||
*
|
||||
* Copyright (c) 2015 Markus Sattler. All rights reserved.
|
||||
* This file is part of the ESP31B core for Arduino.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Arduino.h"
|
||||
extern "C" {
|
||||
#include "libb64/cdecode.h"
|
||||
#include "libb64/cencode.h"
|
||||
}
|
||||
#include "base64.h"
|
||||
|
||||
/**
|
||||
* convert input data to base64
|
||||
* @param data uint8_t *
|
||||
* @param length size_t
|
||||
* @return String
|
||||
*/
|
||||
String base64::encode(uint8_t * data, size_t length)
|
||||
{
|
||||
// base64 needs more size then the source data
|
||||
size_t size = ((length * 1.6f) + 1);
|
||||
char * buffer = (char *) malloc(size);
|
||||
if(buffer) {
|
||||
base64_encodestate _state;
|
||||
base64_init_encodestate(&_state);
|
||||
int len = base64_encode_block((const char *) &data[0], length, &buffer[0], &_state);
|
||||
len = base64_encode_blockend((buffer + len), &_state);
|
||||
|
||||
String base64 = String(buffer);
|
||||
free(buffer);
|
||||
return base64;
|
||||
}
|
||||
return String("-FAIL-");
|
||||
}
|
||||
|
||||
/**
|
||||
* convert input data to base64
|
||||
* @param text String
|
||||
* @return String
|
||||
*/
|
||||
String base64::encode(String text)
|
||||
{
|
||||
return base64::encode((uint8_t *) text.c_str(), text.length());
|
||||
}
|
||||
|
||||
/**
|
||||
* base64.cpp
|
||||
*
|
||||
* Created on: 09.12.2015
|
||||
*
|
||||
* Copyright (c) 2015 Markus Sattler. All rights reserved.
|
||||
* This file is part of the ESP31B core for Arduino.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Arduino.h"
|
||||
extern "C" {
|
||||
#include "libb64/cdecode.h"
|
||||
#include "libb64/cencode.h"
|
||||
}
|
||||
#include "base64.h"
|
||||
|
||||
/**
|
||||
* convert input data to base64
|
||||
* @param data uint8_t *
|
||||
* @param length size_t
|
||||
* @return String
|
||||
*/
|
||||
String base64::encode(uint8_t * data, size_t length)
|
||||
{
|
||||
// base64 needs more size then the source data
|
||||
size_t size = ((length * 1.6f) + 1);
|
||||
char * buffer = (char *) malloc(size);
|
||||
if(buffer) {
|
||||
base64_encodestate _state;
|
||||
base64_init_encodestate(&_state);
|
||||
int len = base64_encode_block((const char *) &data[0], length, &buffer[0], &_state);
|
||||
len = base64_encode_blockend((buffer + len), &_state);
|
||||
|
||||
String base64 = String(buffer);
|
||||
free(buffer);
|
||||
return base64;
|
||||
}
|
||||
return String("-FAIL-");
|
||||
}
|
||||
|
||||
/**
|
||||
* convert input data to base64
|
||||
* @param text String
|
||||
* @return String
|
||||
*/
|
||||
String base64::encode(String text)
|
||||
{
|
||||
return base64::encode((uint8_t *) text.c_str(), text.length());
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
#ifndef CORE_BASE64_H_
|
||||
#define CORE_BASE64_H_
|
||||
|
||||
class base64
|
||||
{
|
||||
public:
|
||||
static String encode(uint8_t * data, size_t length);
|
||||
static String encode(String text);
|
||||
private:
|
||||
};
|
||||
|
||||
|
||||
#endif /* CORE_BASE64_H_ */
|
||||
#ifndef CORE_BASE64_H_
|
||||
#define CORE_BASE64_H_
|
||||
|
||||
class base64
|
||||
{
|
||||
public:
|
||||
static String encode(uint8_t * data, size_t length);
|
||||
static String encode(String text);
|
||||
private:
|
||||
};
|
||||
|
||||
|
||||
#endif /* CORE_BASE64_H_ */
|
||||
|
@ -1,24 +1,24 @@
|
||||
// esp8266-compat.h - Compatibility functions to help ESP8266 libraries and user code run on ESP32
|
||||
|
||||
// Copyright (c) 2017 Evandro Luis Copercini. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _ESP8266_COMPAT_H_
|
||||
#define _ESP8266_COMPAT_H_
|
||||
|
||||
#define ICACHE_FLASH_ATTR
|
||||
#define ICACHE_RAM_ATTR IRAM_ATTR
|
||||
|
||||
|
||||
// esp8266-compat.h - Compatibility functions to help ESP8266 libraries and user code run on ESP32
|
||||
|
||||
// Copyright (c) 2017 Evandro Luis Copercini. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _ESP8266_COMPAT_H_
|
||||
#define _ESP8266_COMPAT_H_
|
||||
|
||||
#define ICACHE_FLASH_ATTR
|
||||
#define ICACHE_RAM_ATTR IRAM_ATTR
|
||||
|
||||
|
||||
#endif /* _ESP8266_COMPAT_H_ */
|
@ -1,81 +1,81 @@
|
||||
/*
|
||||
This sketch shows the Ethernet event usage
|
||||
|
||||
*/
|
||||
|
||||
#include <ETH.h>
|
||||
|
||||
static bool eth_connected = false;
|
||||
|
||||
void WiFiEvent(WiFiEvent_t event)
|
||||
{
|
||||
switch (event) {
|
||||
case SYSTEM_EVENT_ETH_START:
|
||||
Serial.println("ETH Started");
|
||||
//set eth hostname here
|
||||
ETH.setHostname("esp32-ethernet");
|
||||
break;
|
||||
case SYSTEM_EVENT_ETH_CONNECTED:
|
||||
Serial.println("ETH Connected");
|
||||
break;
|
||||
case SYSTEM_EVENT_ETH_GOT_IP:
|
||||
Serial.print("ETH MAC: ");
|
||||
Serial.print(ETH.macAddress());
|
||||
Serial.print(", IPv4: ");
|
||||
Serial.print(ETH.localIP());
|
||||
if (ETH.fullDuplex()) {
|
||||
Serial.print(", FULL_DUPLEX");
|
||||
}
|
||||
Serial.print(", ");
|
||||
Serial.print(ETH.linkSpeed());
|
||||
Serial.println("Mbps");
|
||||
eth_connected = true;
|
||||
break;
|
||||
case SYSTEM_EVENT_ETH_DISCONNECTED:
|
||||
Serial.println("ETH Disconnected");
|
||||
eth_connected = false;
|
||||
break;
|
||||
case SYSTEM_EVENT_ETH_STOP:
|
||||
Serial.println("ETH Stopped");
|
||||
eth_connected = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void testClient(const char * host, uint16_t port)
|
||||
{
|
||||
Serial.print("\nconnecting to ");
|
||||
Serial.println(host);
|
||||
|
||||
WiFiClient client;
|
||||
if (!client.connect(host, port)) {
|
||||
Serial.println("connection failed");
|
||||
return;
|
||||
}
|
||||
client.printf("GET / HTTP/1.1\r\nHost: %s\r\n\r\n", host);
|
||||
while (client.connected() && !client.available());
|
||||
while (client.available()) {
|
||||
Serial.write(client.read());
|
||||
}
|
||||
|
||||
Serial.println("closing connection\n");
|
||||
client.stop();
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
WiFi.onEvent(WiFiEvent);
|
||||
ETH.begin();
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (eth_connected) {
|
||||
testClient("google.com", 80);
|
||||
}
|
||||
delay(10000);
|
||||
}
|
||||
/*
|
||||
This sketch shows the Ethernet event usage
|
||||
|
||||
*/
|
||||
|
||||
#include <ETH.h>
|
||||
|
||||
static bool eth_connected = false;
|
||||
|
||||
void WiFiEvent(WiFiEvent_t event)
|
||||
{
|
||||
switch (event) {
|
||||
case SYSTEM_EVENT_ETH_START:
|
||||
Serial.println("ETH Started");
|
||||
//set eth hostname here
|
||||
ETH.setHostname("esp32-ethernet");
|
||||
break;
|
||||
case SYSTEM_EVENT_ETH_CONNECTED:
|
||||
Serial.println("ETH Connected");
|
||||
break;
|
||||
case SYSTEM_EVENT_ETH_GOT_IP:
|
||||
Serial.print("ETH MAC: ");
|
||||
Serial.print(ETH.macAddress());
|
||||
Serial.print(", IPv4: ");
|
||||
Serial.print(ETH.localIP());
|
||||
if (ETH.fullDuplex()) {
|
||||
Serial.print(", FULL_DUPLEX");
|
||||
}
|
||||
Serial.print(", ");
|
||||
Serial.print(ETH.linkSpeed());
|
||||
Serial.println("Mbps");
|
||||
eth_connected = true;
|
||||
break;
|
||||
case SYSTEM_EVENT_ETH_DISCONNECTED:
|
||||
Serial.println("ETH Disconnected");
|
||||
eth_connected = false;
|
||||
break;
|
||||
case SYSTEM_EVENT_ETH_STOP:
|
||||
Serial.println("ETH Stopped");
|
||||
eth_connected = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void testClient(const char * host, uint16_t port)
|
||||
{
|
||||
Serial.print("\nconnecting to ");
|
||||
Serial.println(host);
|
||||
|
||||
WiFiClient client;
|
||||
if (!client.connect(host, port)) {
|
||||
Serial.println("connection failed");
|
||||
return;
|
||||
}
|
||||
client.printf("GET / HTTP/1.1\r\nHost: %s\r\n\r\n", host);
|
||||
while (client.connected() && !client.available());
|
||||
while (client.available()) {
|
||||
Serial.write(client.read());
|
||||
}
|
||||
|
||||
Serial.println("closing connection\n");
|
||||
client.stop();
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
WiFi.onEvent(WiFiEvent);
|
||||
ETH.begin();
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (eth_connected) {
|
||||
testClient("google.com", 80);
|
||||
}
|
||||
delay(10000);
|
||||
}
|
||||
|
@ -1,87 +1,87 @@
|
||||
/*
|
||||
This sketch shows the Ethernet event usage
|
||||
|
||||
*/
|
||||
|
||||
#include <ETH.h>
|
||||
|
||||
#define ETH_ADDR 31
|
||||
#define ETH_POWER_PIN 17
|
||||
#define ETH_MDC_PIN 23
|
||||
#define ETH_MDIO_PIN 18
|
||||
#define ETH_TYPE ETH_PHY_TLK110
|
||||
|
||||
static bool eth_connected = false;
|
||||
|
||||
void WiFiEvent(WiFiEvent_t event)
|
||||
{
|
||||
switch (event) {
|
||||
case SYSTEM_EVENT_ETH_START:
|
||||
Serial.println("ETH Started");
|
||||
//set eth hostname here
|
||||
ETH.setHostname("esp32-ethernet");
|
||||
break;
|
||||
case SYSTEM_EVENT_ETH_CONNECTED:
|
||||
Serial.println("ETH Connected");
|
||||
break;
|
||||
case SYSTEM_EVENT_ETH_GOT_IP:
|
||||
Serial.print("ETH MAC: ");
|
||||
Serial.print(ETH.macAddress());
|
||||
Serial.print(", IPv4: ");
|
||||
Serial.print(ETH.localIP());
|
||||
if (ETH.fullDuplex()) {
|
||||
Serial.print(", FULL_DUPLEX");
|
||||
}
|
||||
Serial.print(", ");
|
||||
Serial.print(ETH.linkSpeed());
|
||||
Serial.println("Mbps");
|
||||
eth_connected = true;
|
||||
break;
|
||||
case SYSTEM_EVENT_ETH_DISCONNECTED:
|
||||
Serial.println("ETH Disconnected");
|
||||
eth_connected = false;
|
||||
break;
|
||||
case SYSTEM_EVENT_ETH_STOP:
|
||||
Serial.println("ETH Stopped");
|
||||
eth_connected = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void testClient(const char * host, uint16_t port)
|
||||
{
|
||||
Serial.print("\nconnecting to ");
|
||||
Serial.println(host);
|
||||
|
||||
WiFiClient client;
|
||||
if (!client.connect(host, port)) {
|
||||
Serial.println("connection failed");
|
||||
return;
|
||||
}
|
||||
client.printf("GET / HTTP/1.1\r\nHost: %s\r\n\r\n", host);
|
||||
while (client.connected() && !client.available());
|
||||
while (client.available()) {
|
||||
Serial.write(client.read());
|
||||
}
|
||||
|
||||
Serial.println("closing connection\n");
|
||||
client.stop();
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
WiFi.onEvent(WiFiEvent);
|
||||
ETH.begin(ETH_ADDR, ETH_POWER_PIN, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_TYPE);
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (eth_connected) {
|
||||
testClient("google.com", 80);
|
||||
}
|
||||
delay(10000);
|
||||
}
|
||||
/*
|
||||
This sketch shows the Ethernet event usage
|
||||
|
||||
*/
|
||||
|
||||
#include <ETH.h>
|
||||
|
||||
#define ETH_ADDR 31
|
||||
#define ETH_POWER_PIN 17
|
||||
#define ETH_MDC_PIN 23
|
||||
#define ETH_MDIO_PIN 18
|
||||
#define ETH_TYPE ETH_PHY_TLK110
|
||||
|
||||
static bool eth_connected = false;
|
||||
|
||||
void WiFiEvent(WiFiEvent_t event)
|
||||
{
|
||||
switch (event) {
|
||||
case SYSTEM_EVENT_ETH_START:
|
||||
Serial.println("ETH Started");
|
||||
//set eth hostname here
|
||||
ETH.setHostname("esp32-ethernet");
|
||||
break;
|
||||
case SYSTEM_EVENT_ETH_CONNECTED:
|
||||
Serial.println("ETH Connected");
|
||||
break;
|
||||
case SYSTEM_EVENT_ETH_GOT_IP:
|
||||
Serial.print("ETH MAC: ");
|
||||
Serial.print(ETH.macAddress());
|
||||
Serial.print(", IPv4: ");
|
||||
Serial.print(ETH.localIP());
|
||||
if (ETH.fullDuplex()) {
|
||||
Serial.print(", FULL_DUPLEX");
|
||||
}
|
||||
Serial.print(", ");
|
||||
Serial.print(ETH.linkSpeed());
|
||||
Serial.println("Mbps");
|
||||
eth_connected = true;
|
||||
break;
|
||||
case SYSTEM_EVENT_ETH_DISCONNECTED:
|
||||
Serial.println("ETH Disconnected");
|
||||
eth_connected = false;
|
||||
break;
|
||||
case SYSTEM_EVENT_ETH_STOP:
|
||||
Serial.println("ETH Stopped");
|
||||
eth_connected = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void testClient(const char * host, uint16_t port)
|
||||
{
|
||||
Serial.print("\nconnecting to ");
|
||||
Serial.println(host);
|
||||
|
||||
WiFiClient client;
|
||||
if (!client.connect(host, port)) {
|
||||
Serial.println("connection failed");
|
||||
return;
|
||||
}
|
||||
client.printf("GET / HTTP/1.1\r\nHost: %s\r\n\r\n", host);
|
||||
while (client.connected() && !client.available());
|
||||
while (client.available()) {
|
||||
Serial.write(client.read());
|
||||
}
|
||||
|
||||
Serial.println("closing connection\n");
|
||||
client.stop();
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
WiFi.onEvent(WiFiEvent);
|
||||
ETH.begin(ETH_ADDR, ETH_POWER_PIN, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_TYPE);
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (eth_connected) {
|
||||
testClient("google.com", 80);
|
||||
}
|
||||
delay(10000);
|
||||
}
|
||||
|
@ -1,51 +1,51 @@
|
||||
/*
|
||||
* This sketch shows the WiFi event usage
|
||||
*
|
||||
*/
|
||||
|
||||
#include <WiFi.h>
|
||||
|
||||
const char* ssid = "your-ssid";
|
||||
const char* password = "your-password";
|
||||
|
||||
|
||||
void WiFiEvent(WiFiEvent_t event)
|
||||
{
|
||||
Serial.printf("[WiFi-event] event: %d\n", event);
|
||||
|
||||
switch(event) {
|
||||
case SYSTEM_EVENT_STA_GOT_IP:
|
||||
Serial.println("WiFi connected");
|
||||
Serial.println("IP address: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
break;
|
||||
case SYSTEM_EVENT_STA_DISCONNECTED:
|
||||
Serial.println("WiFi lost connection");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
|
||||
// delete old config
|
||||
WiFi.disconnect(true);
|
||||
|
||||
delay(1000);
|
||||
|
||||
WiFi.onEvent(WiFiEvent);
|
||||
|
||||
WiFi.begin(ssid, password);
|
||||
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
Serial.println("Wait for WiFi... ");
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
/*
|
||||
* This sketch shows the WiFi event usage
|
||||
*
|
||||
*/
|
||||
|
||||
#include <WiFi.h>
|
||||
|
||||
const char* ssid = "your-ssid";
|
||||
const char* password = "your-password";
|
||||
|
||||
|
||||
void WiFiEvent(WiFiEvent_t event)
|
||||
{
|
||||
Serial.printf("[WiFi-event] event: %d\n", event);
|
||||
|
||||
switch(event) {
|
||||
case SYSTEM_EVENT_STA_GOT_IP:
|
||||
Serial.println("WiFi connected");
|
||||
Serial.println("IP address: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
break;
|
||||
case SYSTEM_EVENT_STA_DISCONNECTED:
|
||||
Serial.println("WiFi lost connection");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
|
||||
// delete old config
|
||||
WiFi.disconnect(true);
|
||||
|
||||
delay(1000);
|
||||
|
||||
WiFi.onEvent(WiFiEvent);
|
||||
|
||||
WiFi.begin(ssid, password);
|
||||
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
Serial.println("Wait for WiFi... ");
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
|
@ -89,4 +89,4 @@ void loop()
|
||||
Serial.println();
|
||||
Serial.println("closing connection");
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,293 +1,293 @@
|
||||
/*
|
||||
ESP8266WiFiSTA.cpp - WiFi library for esp8266
|
||||
|
||||
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
|
||||
This file is part of the esp8266 core for Arduino environment.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Reworked on 28 Dec 2015 by Markus Sattler
|
||||
|
||||
*/
|
||||
|
||||
#include "WiFi.h"
|
||||
#include "WiFiGeneric.h"
|
||||
#include "WiFiAP.h"
|
||||
|
||||
extern "C" {
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include <esp_err.h>
|
||||
#include <esp_wifi.h>
|
||||
#include <esp_event_loop.h>
|
||||
#include <lwip/ip_addr.h>
|
||||
#include "apps/dhcpserver_options.h"
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------------
|
||||
// ---------------------------------------------------- Private functions ------------------------------------------------
|
||||
// -----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
static bool softap_config_equal(const wifi_config_t& lhs, const wifi_config_t& rhs);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* compare two AP configurations
|
||||
* @param lhs softap_config
|
||||
* @param rhs softap_config
|
||||
* @return equal
|
||||
*/
|
||||
static bool softap_config_equal(const wifi_config_t& lhs, const wifi_config_t& rhs)
|
||||
{
|
||||
if(strcmp(reinterpret_cast<const char*>(lhs.ap.ssid), reinterpret_cast<const char*>(rhs.ap.ssid)) != 0) {
|
||||
return false;
|
||||
}
|
||||
if(strcmp(reinterpret_cast<const char*>(lhs.ap.password), reinterpret_cast<const char*>(rhs.ap.password)) != 0) {
|
||||
return false;
|
||||
}
|
||||
if(lhs.ap.channel != rhs.ap.channel) {
|
||||
return false;
|
||||
}
|
||||
if(lhs.ap.ssid_hidden != rhs.ap.ssid_hidden) {
|
||||
return false;
|
||||
}
|
||||
if(lhs.ap.max_connection != rhs.ap.max_connection) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------- AP function -----------------------------------------------------
|
||||
// -----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* Set up an access point
|
||||
* @param ssid Pointer to the SSID (max 63 char).
|
||||
* @param passphrase (for WPA2 min 8 char, for open use NULL)
|
||||
* @param channel WiFi channel number, 1 - 13.
|
||||
* @param ssid_hidden Network cloaking (0 = broadcast SSID, 1 = hide SSID)
|
||||
* @param max_connection Max simultaneous connected clients, 1 - 4.
|
||||
*/
|
||||
bool WiFiAPClass::softAP(const char* ssid, const char* passphrase, int channel, int ssid_hidden, int max_connection)
|
||||
{
|
||||
|
||||
if(!WiFi.enableAP(true)) {
|
||||
// enable AP failed
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!ssid || *ssid == 0 || strlen(ssid) > 31) {
|
||||
// fail SSID too long or missing!
|
||||
return false;
|
||||
}
|
||||
|
||||
if(passphrase && (strlen(passphrase) > 63 || strlen(passphrase) < 8)) {
|
||||
// fail passphrase to long or short!
|
||||
return false;
|
||||
}
|
||||
|
||||
esp_wifi_start();
|
||||
|
||||
wifi_config_t conf;
|
||||
strcpy(reinterpret_cast<char*>(conf.ap.ssid), ssid);
|
||||
conf.ap.channel = channel;
|
||||
conf.ap.ssid_len = strlen(ssid);
|
||||
conf.ap.ssid_hidden = ssid_hidden;
|
||||
conf.ap.max_connection = max_connection;
|
||||
conf.ap.beacon_interval = 100;
|
||||
|
||||
if(!passphrase || strlen(passphrase) == 0) {
|
||||
conf.ap.authmode = WIFI_AUTH_OPEN;
|
||||
*conf.ap.password = 0;
|
||||
} else {
|
||||
conf.ap.authmode = WIFI_AUTH_WPA2_PSK;
|
||||
strcpy(reinterpret_cast<char*>(conf.ap.password), passphrase);
|
||||
}
|
||||
|
||||
wifi_config_t conf_current;
|
||||
esp_wifi_get_config(WIFI_IF_AP, &conf_current);
|
||||
if(!softap_config_equal(conf, conf_current) && esp_wifi_set_config(WIFI_IF_AP, &conf) != ESP_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Configure access point
|
||||
* @param local_ip access point IP
|
||||
* @param gateway gateway IP
|
||||
* @param subnet subnet mask
|
||||
*/
|
||||
bool WiFiAPClass::softAPConfig(IPAddress local_ip, IPAddress gateway, IPAddress subnet)
|
||||
{
|
||||
|
||||
if(!WiFi.enableAP(true)) {
|
||||
// enable AP failed
|
||||
return false;
|
||||
}
|
||||
|
||||
esp_wifi_start();
|
||||
|
||||
tcpip_adapter_ip_info_t info;
|
||||
info.ip.addr = static_cast<uint32_t>(local_ip);
|
||||
info.gw.addr = static_cast<uint32_t>(gateway);
|
||||
info.netmask.addr = static_cast<uint32_t>(subnet);
|
||||
tcpip_adapter_dhcps_stop(TCPIP_ADAPTER_IF_AP);
|
||||
if(tcpip_adapter_set_ip_info(TCPIP_ADAPTER_IF_AP, &info) == ESP_OK) {
|
||||
dhcps_lease_t lease;
|
||||
lease.enable = true;
|
||||
lease.start_ip.addr = static_cast<uint32_t>(local_ip) + (1 << 24);
|
||||
lease.end_ip.addr = static_cast<uint32_t>(local_ip) + (11 << 24);
|
||||
|
||||
tcpip_adapter_dhcps_option(
|
||||
(tcpip_adapter_option_mode_t)TCPIP_ADAPTER_OP_SET,
|
||||
(tcpip_adapter_option_id_t)REQUESTED_IP_ADDRESS,
|
||||
(void*)&lease, sizeof(dhcps_lease_t)
|
||||
);
|
||||
|
||||
return tcpip_adapter_dhcps_start(TCPIP_ADAPTER_IF_AP) == ESP_OK;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Disconnect from the network (close AP)
|
||||
* @param wifioff disable mode?
|
||||
* @return one value of wl_status_t enum
|
||||
*/
|
||||
bool WiFiAPClass::softAPdisconnect(bool wifioff)
|
||||
{
|
||||
bool ret;
|
||||
wifi_config_t conf;
|
||||
*conf.ap.ssid = 0;
|
||||
*conf.ap.password = 0;
|
||||
conf.ap.authmode = WIFI_AUTH_OPEN; // auth must be open if pass=0
|
||||
ret = esp_wifi_set_config(WIFI_IF_AP, &conf) == ESP_OK;
|
||||
|
||||
if(wifioff) {
|
||||
ret = WiFi.enableAP(false) == ESP_OK;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the count of the Station / client that are connected to the softAP interface
|
||||
* @return Stations count
|
||||
*/
|
||||
uint8_t WiFiAPClass::softAPgetStationNum()
|
||||
{
|
||||
wifi_sta_list_t clients;
|
||||
if(esp_wifi_ap_get_sta_list(&clients) == ESP_OK) {
|
||||
return clients.num;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the softAP interface IP address.
|
||||
* @return IPAddress softAP IP
|
||||
*/
|
||||
IPAddress WiFiAPClass::softAPIP()
|
||||
{
|
||||
tcpip_adapter_ip_info_t ip;
|
||||
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &ip);
|
||||
return IPAddress(ip.ip.addr);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the softAP interface MAC address.
|
||||
* @param mac pointer to uint8_t array with length WL_MAC_ADDR_LENGTH
|
||||
* @return pointer to uint8_t*
|
||||
*/
|
||||
uint8_t* WiFiAPClass::softAPmacAddress(uint8_t* mac)
|
||||
{
|
||||
esp_wifi_get_mac(WIFI_IF_AP, mac);
|
||||
return mac;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the softAP interface MAC address.
|
||||
* @return String mac
|
||||
*/
|
||||
String WiFiAPClass::softAPmacAddress(void)
|
||||
{
|
||||
uint8_t mac[6];
|
||||
char macStr[18] = { 0 };
|
||||
esp_wifi_get_mac(WIFI_IF_AP, mac);
|
||||
|
||||
sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
return String(macStr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the softAP interface Host name.
|
||||
* @return char array hostname
|
||||
*/
|
||||
const char * WiFiAPClass::softAPgetHostname()
|
||||
{
|
||||
const char * hostname;
|
||||
if(tcpip_adapter_get_hostname(TCPIP_ADAPTER_IF_AP, &hostname)) {
|
||||
return NULL;
|
||||
}
|
||||
return hostname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the softAP interface Host name.
|
||||
* @param hostname pointer to const string
|
||||
* @return true on success
|
||||
*/
|
||||
bool WiFiAPClass::softAPsetHostname(const char * hostname)
|
||||
{
|
||||
return tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_AP, hostname) == ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable IPv6 on the softAP interface.
|
||||
* @return true on success
|
||||
*/
|
||||
bool WiFiAPClass::softAPenableIpV6()
|
||||
{
|
||||
return tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_AP) == ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the softAP interface IPv6 address.
|
||||
* @return IPv6Address softAP IPv6
|
||||
*/
|
||||
IPv6Address WiFiAPClass::softAPIPv6()
|
||||
{
|
||||
static ip6_addr_t addr;
|
||||
if(tcpip_adapter_get_ip6_linklocal(TCPIP_ADAPTER_IF_AP, &addr)) {
|
||||
return IPv6Address();
|
||||
}
|
||||
return IPv6Address(addr.addr);
|
||||
}
|
||||
/*
|
||||
ESP8266WiFiSTA.cpp - WiFi library for esp8266
|
||||
|
||||
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
|
||||
This file is part of the esp8266 core for Arduino environment.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Reworked on 28 Dec 2015 by Markus Sattler
|
||||
|
||||
*/
|
||||
|
||||
#include "WiFi.h"
|
||||
#include "WiFiGeneric.h"
|
||||
#include "WiFiAP.h"
|
||||
|
||||
extern "C" {
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include <esp_err.h>
|
||||
#include <esp_wifi.h>
|
||||
#include <esp_event_loop.h>
|
||||
#include <lwip/ip_addr.h>
|
||||
#include "apps/dhcpserver_options.h"
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------------
|
||||
// ---------------------------------------------------- Private functions ------------------------------------------------
|
||||
// -----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
static bool softap_config_equal(const wifi_config_t& lhs, const wifi_config_t& rhs);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* compare two AP configurations
|
||||
* @param lhs softap_config
|
||||
* @param rhs softap_config
|
||||
* @return equal
|
||||
*/
|
||||
static bool softap_config_equal(const wifi_config_t& lhs, const wifi_config_t& rhs)
|
||||
{
|
||||
if(strcmp(reinterpret_cast<const char*>(lhs.ap.ssid), reinterpret_cast<const char*>(rhs.ap.ssid)) != 0) {
|
||||
return false;
|
||||
}
|
||||
if(strcmp(reinterpret_cast<const char*>(lhs.ap.password), reinterpret_cast<const char*>(rhs.ap.password)) != 0) {
|
||||
return false;
|
||||
}
|
||||
if(lhs.ap.channel != rhs.ap.channel) {
|
||||
return false;
|
||||
}
|
||||
if(lhs.ap.ssid_hidden != rhs.ap.ssid_hidden) {
|
||||
return false;
|
||||
}
|
||||
if(lhs.ap.max_connection != rhs.ap.max_connection) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------- AP function -----------------------------------------------------
|
||||
// -----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* Set up an access point
|
||||
* @param ssid Pointer to the SSID (max 63 char).
|
||||
* @param passphrase (for WPA2 min 8 char, for open use NULL)
|
||||
* @param channel WiFi channel number, 1 - 13.
|
||||
* @param ssid_hidden Network cloaking (0 = broadcast SSID, 1 = hide SSID)
|
||||
* @param max_connection Max simultaneous connected clients, 1 - 4.
|
||||
*/
|
||||
bool WiFiAPClass::softAP(const char* ssid, const char* passphrase, int channel, int ssid_hidden, int max_connection)
|
||||
{
|
||||
|
||||
if(!WiFi.enableAP(true)) {
|
||||
// enable AP failed
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!ssid || *ssid == 0 || strlen(ssid) > 31) {
|
||||
// fail SSID too long or missing!
|
||||
return false;
|
||||
}
|
||||
|
||||
if(passphrase && (strlen(passphrase) > 63 || strlen(passphrase) < 8)) {
|
||||
// fail passphrase to long or short!
|
||||
return false;
|
||||
}
|
||||
|
||||
esp_wifi_start();
|
||||
|
||||
wifi_config_t conf;
|
||||
strcpy(reinterpret_cast<char*>(conf.ap.ssid), ssid);
|
||||
conf.ap.channel = channel;
|
||||
conf.ap.ssid_len = strlen(ssid);
|
||||
conf.ap.ssid_hidden = ssid_hidden;
|
||||
conf.ap.max_connection = max_connection;
|
||||
conf.ap.beacon_interval = 100;
|
||||
|
||||
if(!passphrase || strlen(passphrase) == 0) {
|
||||
conf.ap.authmode = WIFI_AUTH_OPEN;
|
||||
*conf.ap.password = 0;
|
||||
} else {
|
||||
conf.ap.authmode = WIFI_AUTH_WPA2_PSK;
|
||||
strcpy(reinterpret_cast<char*>(conf.ap.password), passphrase);
|
||||
}
|
||||
|
||||
wifi_config_t conf_current;
|
||||
esp_wifi_get_config(WIFI_IF_AP, &conf_current);
|
||||
if(!softap_config_equal(conf, conf_current) && esp_wifi_set_config(WIFI_IF_AP, &conf) != ESP_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Configure access point
|
||||
* @param local_ip access point IP
|
||||
* @param gateway gateway IP
|
||||
* @param subnet subnet mask
|
||||
*/
|
||||
bool WiFiAPClass::softAPConfig(IPAddress local_ip, IPAddress gateway, IPAddress subnet)
|
||||
{
|
||||
|
||||
if(!WiFi.enableAP(true)) {
|
||||
// enable AP failed
|
||||
return false;
|
||||
}
|
||||
|
||||
esp_wifi_start();
|
||||
|
||||
tcpip_adapter_ip_info_t info;
|
||||
info.ip.addr = static_cast<uint32_t>(local_ip);
|
||||
info.gw.addr = static_cast<uint32_t>(gateway);
|
||||
info.netmask.addr = static_cast<uint32_t>(subnet);
|
||||
tcpip_adapter_dhcps_stop(TCPIP_ADAPTER_IF_AP);
|
||||
if(tcpip_adapter_set_ip_info(TCPIP_ADAPTER_IF_AP, &info) == ESP_OK) {
|
||||
dhcps_lease_t lease;
|
||||
lease.enable = true;
|
||||
lease.start_ip.addr = static_cast<uint32_t>(local_ip) + (1 << 24);
|
||||
lease.end_ip.addr = static_cast<uint32_t>(local_ip) + (11 << 24);
|
||||
|
||||
tcpip_adapter_dhcps_option(
|
||||
(tcpip_adapter_option_mode_t)TCPIP_ADAPTER_OP_SET,
|
||||
(tcpip_adapter_option_id_t)REQUESTED_IP_ADDRESS,
|
||||
(void*)&lease, sizeof(dhcps_lease_t)
|
||||
);
|
||||
|
||||
return tcpip_adapter_dhcps_start(TCPIP_ADAPTER_IF_AP) == ESP_OK;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Disconnect from the network (close AP)
|
||||
* @param wifioff disable mode?
|
||||
* @return one value of wl_status_t enum
|
||||
*/
|
||||
bool WiFiAPClass::softAPdisconnect(bool wifioff)
|
||||
{
|
||||
bool ret;
|
||||
wifi_config_t conf;
|
||||
*conf.ap.ssid = 0;
|
||||
*conf.ap.password = 0;
|
||||
conf.ap.authmode = WIFI_AUTH_OPEN; // auth must be open if pass=0
|
||||
ret = esp_wifi_set_config(WIFI_IF_AP, &conf) == ESP_OK;
|
||||
|
||||
if(wifioff) {
|
||||
ret = WiFi.enableAP(false) == ESP_OK;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the count of the Station / client that are connected to the softAP interface
|
||||
* @return Stations count
|
||||
*/
|
||||
uint8_t WiFiAPClass::softAPgetStationNum()
|
||||
{
|
||||
wifi_sta_list_t clients;
|
||||
if(esp_wifi_ap_get_sta_list(&clients) == ESP_OK) {
|
||||
return clients.num;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the softAP interface IP address.
|
||||
* @return IPAddress softAP IP
|
||||
*/
|
||||
IPAddress WiFiAPClass::softAPIP()
|
||||
{
|
||||
tcpip_adapter_ip_info_t ip;
|
||||
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &ip);
|
||||
return IPAddress(ip.ip.addr);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the softAP interface MAC address.
|
||||
* @param mac pointer to uint8_t array with length WL_MAC_ADDR_LENGTH
|
||||
* @return pointer to uint8_t*
|
||||
*/
|
||||
uint8_t* WiFiAPClass::softAPmacAddress(uint8_t* mac)
|
||||
{
|
||||
esp_wifi_get_mac(WIFI_IF_AP, mac);
|
||||
return mac;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the softAP interface MAC address.
|
||||
* @return String mac
|
||||
*/
|
||||
String WiFiAPClass::softAPmacAddress(void)
|
||||
{
|
||||
uint8_t mac[6];
|
||||
char macStr[18] = { 0 };
|
||||
esp_wifi_get_mac(WIFI_IF_AP, mac);
|
||||
|
||||
sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
return String(macStr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the softAP interface Host name.
|
||||
* @return char array hostname
|
||||
*/
|
||||
const char * WiFiAPClass::softAPgetHostname()
|
||||
{
|
||||
const char * hostname;
|
||||
if(tcpip_adapter_get_hostname(TCPIP_ADAPTER_IF_AP, &hostname)) {
|
||||
return NULL;
|
||||
}
|
||||
return hostname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the softAP interface Host name.
|
||||
* @param hostname pointer to const string
|
||||
* @return true on success
|
||||
*/
|
||||
bool WiFiAPClass::softAPsetHostname(const char * hostname)
|
||||
{
|
||||
return tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_AP, hostname) == ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable IPv6 on the softAP interface.
|
||||
* @return true on success
|
||||
*/
|
||||
bool WiFiAPClass::softAPenableIpV6()
|
||||
{
|
||||
return tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_AP) == ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the softAP interface IPv6 address.
|
||||
* @return IPv6Address softAP IPv6
|
||||
*/
|
||||
IPv6Address WiFiAPClass::softAPIPv6()
|
||||
{
|
||||
static ip6_addr_t addr;
|
||||
if(tcpip_adapter_get_ip6_linklocal(TCPIP_ADAPTER_IF_AP, &addr)) {
|
||||
return IPv6Address();
|
||||
}
|
||||
return IPv6Address(addr.addr);
|
||||
}
|
||||
|
@ -1,61 +1,61 @@
|
||||
/*
|
||||
ESP8266WiFiAP.h - esp8266 Wifi support.
|
||||
Based on WiFi.h from Arduino WiFi shield library.
|
||||
Copyright (c) 2011-2014 Arduino. All right reserved.
|
||||
Modified by Ivan Grokhotkov, December 2014
|
||||
Reworked by Markus Sattler, December 2015
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef ESP32WIFIAP_H_
|
||||
#define ESP32WIFIAP_H_
|
||||
|
||||
|
||||
#include "WiFiType.h"
|
||||
#include "WiFiGeneric.h"
|
||||
|
||||
|
||||
class WiFiAPClass
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------------------------
|
||||
// ----------------------------------------- AP function ----------------------------------------
|
||||
// ----------------------------------------------------------------------------------------------
|
||||
|
||||
public:
|
||||
|
||||
bool softAP(const char* ssid, const char* passphrase = NULL, int channel = 1, int ssid_hidden = 0, int max_connection = 4);
|
||||
bool softAPConfig(IPAddress local_ip, IPAddress gateway, IPAddress subnet);
|
||||
bool softAPdisconnect(bool wifioff = false);
|
||||
|
||||
uint8_t softAPgetStationNum();
|
||||
|
||||
IPAddress softAPIP();
|
||||
|
||||
bool softAPenableIpV6();
|
||||
IPv6Address softAPIPv6();
|
||||
|
||||
const char * softAPgetHostname();
|
||||
bool softAPsetHostname(const char * hostname);
|
||||
|
||||
uint8_t* softAPmacAddress(uint8_t* mac);
|
||||
String softAPmacAddress(void);
|
||||
|
||||
protected:
|
||||
|
||||
};
|
||||
|
||||
#endif /* ESP32WIFIAP_H_*/
|
||||
/*
|
||||
ESP8266WiFiAP.h - esp8266 Wifi support.
|
||||
Based on WiFi.h from Arduino WiFi shield library.
|
||||
Copyright (c) 2011-2014 Arduino. All right reserved.
|
||||
Modified by Ivan Grokhotkov, December 2014
|
||||
Reworked by Markus Sattler, December 2015
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef ESP32WIFIAP_H_
|
||||
#define ESP32WIFIAP_H_
|
||||
|
||||
|
||||
#include "WiFiType.h"
|
||||
#include "WiFiGeneric.h"
|
||||
|
||||
|
||||
class WiFiAPClass
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------------------------
|
||||
// ----------------------------------------- AP function ----------------------------------------
|
||||
// ----------------------------------------------------------------------------------------------
|
||||
|
||||
public:
|
||||
|
||||
bool softAP(const char* ssid, const char* passphrase = NULL, int channel = 1, int ssid_hidden = 0, int max_connection = 4);
|
||||
bool softAPConfig(IPAddress local_ip, IPAddress gateway, IPAddress subnet);
|
||||
bool softAPdisconnect(bool wifioff = false);
|
||||
|
||||
uint8_t softAPgetStationNum();
|
||||
|
||||
IPAddress softAPIP();
|
||||
|
||||
bool softAPenableIpV6();
|
||||
IPv6Address softAPIPv6();
|
||||
|
||||
const char * softAPgetHostname();
|
||||
bool softAPsetHostname(const char * hostname);
|
||||
|
||||
uint8_t* softAPmacAddress(uint8_t* mac);
|
||||
String softAPmacAddress(void);
|
||||
|
||||
protected:
|
||||
|
||||
};
|
||||
|
||||
#endif /* ESP32WIFIAP_H_*/
|
||||
|
@ -1,497 +1,497 @@
|
||||
/*
|
||||
ESP8266WiFiGeneric.cpp - WiFi library for esp8266
|
||||
|
||||
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
|
||||
This file is part of the esp8266 core for Arduino environment.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Reworked on 28 Dec 2015 by Markus Sattler
|
||||
|
||||
*/
|
||||
|
||||
#include "WiFi.h"
|
||||
#include "WiFiGeneric.h"
|
||||
|
||||
extern "C" {
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <esp_err.h>
|
||||
#include <esp_wifi.h>
|
||||
#include <esp_event_loop.h>
|
||||
#include "lwip/ip_addr.h"
|
||||
#include "lwip/opt.h"
|
||||
#include "lwip/err.h"
|
||||
#include "lwip/dns.h"
|
||||
#include "esp_ipc.h"
|
||||
|
||||
|
||||
} //extern "C"
|
||||
|
||||
#include "esp32-hal-log.h"
|
||||
|
||||
#undef min
|
||||
#undef max
|
||||
#include <vector>
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#if CONFIG_FREERTOS_UNICORE
|
||||
#define ARDUINO_RUNNING_CORE 0
|
||||
#else
|
||||
#define ARDUINO_RUNNING_CORE 1
|
||||
#endif
|
||||
|
||||
static xQueueHandle _network_event_queue;
|
||||
static TaskHandle_t _network_event_task_handle = NULL;
|
||||
|
||||
static void _network_event_task(void * arg){
|
||||
system_event_t *event = NULL;
|
||||
for (;;) {
|
||||
if(xQueueReceive(_network_event_queue, &event, portMAX_DELAY) == pdTRUE){
|
||||
WiFiGenericClass::_eventCallback(arg, event);
|
||||
}
|
||||
}
|
||||
vTaskDelete(NULL);
|
||||
_network_event_task_handle = NULL;
|
||||
}
|
||||
|
||||
static esp_err_t _network_event_cb(void *arg, system_event_t *event){
|
||||
if (xQueueSend(_network_event_queue, &event, portMAX_DELAY) != pdPASS) {
|
||||
log_w("Network Event Queue Send Failed!");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void _start_network_event_task(){
|
||||
if(!_network_event_queue){
|
||||
_network_event_queue = xQueueCreate(32, sizeof(system_event_t *));
|
||||
if(!_network_event_queue){
|
||||
log_e("Network Event Queue Create Failed!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(!_network_event_task_handle){
|
||||
xTaskCreatePinnedToCore(_network_event_task, "network_event", 4096, NULL, 2, &_network_event_task_handle, ARDUINO_RUNNING_CORE);
|
||||
if(!_network_event_task_handle){
|
||||
log_e("Network Event Task Start Failed!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
esp_event_loop_init(&_network_event_cb, NULL);
|
||||
}
|
||||
|
||||
void tcpipInit(){
|
||||
static bool initialized = false;
|
||||
if(!initialized){
|
||||
initialized = true;
|
||||
_start_network_event_task();
|
||||
tcpip_adapter_init();
|
||||
}
|
||||
}
|
||||
|
||||
static bool wifiLowLevelInit(){
|
||||
static bool lowLevelInitDone = false;
|
||||
if(!lowLevelInitDone){
|
||||
tcpipInit();
|
||||
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
||||
esp_err_t err = esp_wifi_init(&cfg);
|
||||
if(err){
|
||||
log_e("esp_wifi_init %d", err);
|
||||
return false;
|
||||
}
|
||||
esp_wifi_set_storage(WIFI_STORAGE_FLASH);
|
||||
esp_wifi_set_mode(WIFI_MODE_NULL);
|
||||
lowLevelInitDone = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool wifiLowLevelDeinit(){
|
||||
//deinit not working yet!
|
||||
//esp_wifi_deinit();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _esp_wifi_started = false;
|
||||
|
||||
static bool espWiFiStart(){
|
||||
if(_esp_wifi_started){
|
||||
return true;
|
||||
}
|
||||
if(!wifiLowLevelInit()){
|
||||
return false;
|
||||
}
|
||||
esp_err_t err = esp_wifi_start();
|
||||
if (err != ESP_OK) {
|
||||
log_e("esp_wifi_start %d", err);
|
||||
wifiLowLevelDeinit();
|
||||
return false;
|
||||
}
|
||||
_esp_wifi_started = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool espWiFiStop(){
|
||||
esp_err_t err;
|
||||
if(!_esp_wifi_started){
|
||||
return true;
|
||||
}
|
||||
err = esp_wifi_stop();
|
||||
if(err){
|
||||
log_e("Could not stop WiFi! %u", err);
|
||||
return false;
|
||||
}
|
||||
_esp_wifi_started = false;
|
||||
return wifiLowLevelDeinit();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------- Generic WiFi function -----------------------------------------------
|
||||
// -----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
typedef struct {
|
||||
WiFiEventCb cb;
|
||||
WiFiEventFullCb fcb;
|
||||
WiFiEventSysCb scb;
|
||||
system_event_id_t event;
|
||||
} WiFiEventCbList_t;
|
||||
|
||||
// arduino dont like std::vectors move static here
|
||||
static std::vector<WiFiEventCbList_t> cbEventList;
|
||||
|
||||
bool WiFiGenericClass::_persistent = true;
|
||||
wifi_mode_t WiFiGenericClass::_forceSleepLastMode = WIFI_MODE_NULL;
|
||||
|
||||
WiFiGenericClass::WiFiGenericClass()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* set callback function
|
||||
* @param cbEvent WiFiEventCb
|
||||
* @param event optional filter (WIFI_EVENT_MAX is all events)
|
||||
*/
|
||||
void WiFiGenericClass::onEvent(WiFiEventCb cbEvent, system_event_id_t event)
|
||||
{
|
||||
if(!cbEvent) {
|
||||
return;
|
||||
}
|
||||
WiFiEventCbList_t newEventHandler;
|
||||
newEventHandler.cb = cbEvent;
|
||||
newEventHandler.fcb = NULL;
|
||||
newEventHandler.scb = NULL;
|
||||
newEventHandler.event = event;
|
||||
cbEventList.push_back(newEventHandler);
|
||||
}
|
||||
|
||||
void WiFiGenericClass::onEvent(WiFiEventFullCb cbEvent, system_event_id_t event)
|
||||
{
|
||||
if(!cbEvent) {
|
||||
return;
|
||||
}
|
||||
WiFiEventCbList_t newEventHandler;
|
||||
newEventHandler.cb = NULL;
|
||||
newEventHandler.fcb = cbEvent;
|
||||
newEventHandler.scb = NULL;
|
||||
newEventHandler.event = event;
|
||||
cbEventList.push_back(newEventHandler);
|
||||
}
|
||||
|
||||
void WiFiGenericClass::onEvent(WiFiEventSysCb cbEvent, system_event_id_t event)
|
||||
{
|
||||
if(!cbEvent) {
|
||||
return;
|
||||
}
|
||||
WiFiEventCbList_t newEventHandler;
|
||||
newEventHandler.cb = NULL;
|
||||
newEventHandler.fcb = NULL;
|
||||
newEventHandler.scb = cbEvent;
|
||||
newEventHandler.event = event;
|
||||
cbEventList.push_back(newEventHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* removes a callback form event handler
|
||||
* @param cbEvent WiFiEventCb
|
||||
* @param event optional filter (WIFI_EVENT_MAX is all events)
|
||||
*/
|
||||
void WiFiGenericClass::removeEvent(WiFiEventCb cbEvent, system_event_id_t event)
|
||||
{
|
||||
if(!cbEvent) {
|
||||
return;
|
||||
}
|
||||
|
||||
for(uint32_t i = 0; i < cbEventList.size(); i++) {
|
||||
WiFiEventCbList_t entry = cbEventList[i];
|
||||
if(entry.cb == cbEvent && entry.event == event) {
|
||||
cbEventList.erase(cbEventList.begin() + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WiFiGenericClass::removeEvent(WiFiEventFullCb cbEvent, system_event_id_t event)
|
||||
{
|
||||
if(!cbEvent) {
|
||||
return;
|
||||
}
|
||||
|
||||
for(uint32_t i = 0; i < cbEventList.size(); i++) {
|
||||
WiFiEventCbList_t entry = cbEventList[i];
|
||||
if(entry.fcb == cbEvent && entry.event == event) {
|
||||
cbEventList.erase(cbEventList.begin() + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WiFiGenericClass::removeEvent(WiFiEventSysCb cbEvent, system_event_id_t event)
|
||||
{
|
||||
if(!cbEvent) {
|
||||
return;
|
||||
}
|
||||
|
||||
for(uint32_t i = 0; i < cbEventList.size(); i++) {
|
||||
WiFiEventCbList_t entry = cbEventList[i];
|
||||
if(entry.scb == cbEvent && entry.event == event) {
|
||||
cbEventList.erase(cbEventList.begin() + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* callback for WiFi events
|
||||
* @param arg
|
||||
*/
|
||||
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_DEBUG
|
||||
const char * system_event_names[] = { "WIFI_READY", "SCAN_DONE", "STA_START", "STA_STOP", "STA_CONNECTED", "STA_DISCONNECTED", "STA_AUTHMODE_CHANGE", "STA_GOT_IP", "STA_LOST_IP", "STA_WPS_ER_SUCCESS", "STA_WPS_ER_FAILED", "STA_WPS_ER_TIMEOUT", "STA_WPS_ER_PIN", "AP_START", "AP_STOP", "AP_STACONNECTED", "AP_STADISCONNECTED", "AP_PROBEREQRECVED", "GOT_IP6", "ETH_START", "ETH_STOP", "ETH_CONNECTED", "ETH_DISCONNECTED", "ETH_GOT_IP", "MAX"};
|
||||
#endif
|
||||
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_WARN
|
||||
const char * system_event_reasons[] = { "UNSPECIFIED", "AUTH_EXPIRE", "AUTH_LEAVE", "ASSOC_EXPIRE", "ASSOC_TOOMANY", "NOT_AUTHED", "NOT_ASSOCED", "ASSOC_LEAVE", "ASSOC_NOT_AUTHED", "DISASSOC_PWRCAP_BAD", "DISASSOC_SUPCHAN_BAD", "IE_INVALID", "MIC_FAILURE", "4WAY_HANDSHAKE_TIMEOUT", "GROUP_KEY_UPDATE_TIMEOUT", "IE_IN_4WAY_DIFFERS", "GROUP_CIPHER_INVALID", "PAIRWISE_CIPHER_INVALID", "AKMP_INVALID", "UNSUPP_RSN_IE_VERSION", "INVALID_RSN_IE_CAP", "802_1X_AUTH_FAILED", "CIPHER_SUITE_REJECTED", "BEACON_TIMEOUT", "NO_AP_FOUND", "AUTH_FAIL", "ASSOC_FAIL", "HANDSHAKE_TIMEOUT" };
|
||||
#define reason2str(r) ((r>176)?system_event_reasons[r-177]:system_event_reasons[r-1])
|
||||
#endif
|
||||
esp_err_t WiFiGenericClass::_eventCallback(void *arg, system_event_t *event)
|
||||
{
|
||||
log_d("Event: %d - %s", event->event_id, system_event_names[event->event_id]);
|
||||
if(event->event_id == SYSTEM_EVENT_SCAN_DONE) {
|
||||
WiFiScanClass::_scanDone();
|
||||
} else if(event->event_id == SYSTEM_EVENT_STA_DISCONNECTED) {
|
||||
uint8_t reason = event->event_info.disconnected.reason;
|
||||
log_w("Reason: %u - %s", reason, reason2str(reason));
|
||||
if(reason == WIFI_REASON_NO_AP_FOUND) {
|
||||
WiFiSTAClass::_setStatus(WL_NO_SSID_AVAIL);
|
||||
} else if(reason == WIFI_REASON_AUTH_FAIL || reason == WIFI_REASON_ASSOC_FAIL) {
|
||||
WiFiSTAClass::_setStatus(WL_CONNECT_FAILED);
|
||||
} else if(reason == WIFI_REASON_BEACON_TIMEOUT || reason == WIFI_REASON_HANDSHAKE_TIMEOUT) {
|
||||
WiFiSTAClass::_setStatus(WL_CONNECTION_LOST);
|
||||
} else if(reason == WIFI_REASON_AUTH_EXPIRE) {
|
||||
if(WiFi.getAutoReconnect()){
|
||||
WiFi.begin();
|
||||
}
|
||||
} else {
|
||||
WiFiSTAClass::_setStatus(WL_DISCONNECTED);
|
||||
}
|
||||
} else if(event->event_id == SYSTEM_EVENT_STA_START) {
|
||||
WiFiSTAClass::_setStatus(WL_DISCONNECTED);
|
||||
} else if(event->event_id == SYSTEM_EVENT_STA_STOP) {
|
||||
WiFiSTAClass::_setStatus(WL_NO_SHIELD);
|
||||
} else if(event->event_id == SYSTEM_EVENT_STA_CONNECTED) {
|
||||
WiFiSTAClass::_setStatus(WL_IDLE_STATUS);
|
||||
} else if(event->event_id == SYSTEM_EVENT_STA_GOT_IP) {
|
||||
//#1081 https://github.com/espressif/arduino-esp32/issues/1081
|
||||
// if(WiFiSTAClass::status() == WL_IDLE_STATUS)
|
||||
{
|
||||
WiFiSTAClass::_setStatus(WL_CONNECTED);
|
||||
}
|
||||
}
|
||||
|
||||
for(uint32_t i = 0; i < cbEventList.size(); i++) {
|
||||
WiFiEventCbList_t entry = cbEventList[i];
|
||||
if(entry.cb || entry.fcb || entry.scb) {
|
||||
if(entry.event == (system_event_id_t) event->event_id || entry.event == SYSTEM_EVENT_MAX) {
|
||||
if(entry.cb){
|
||||
entry.cb((system_event_id_t) event->event_id);
|
||||
} else if(entry.fcb){
|
||||
entry.fcb((system_event_id_t) event->event_id, (system_event_info_t) event->event_info);
|
||||
} else {
|
||||
entry.scb(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current channel associated with the network
|
||||
* @return channel (1-13)
|
||||
*/
|
||||
int32_t WiFiGenericClass::channel(void)
|
||||
{
|
||||
uint8_t primaryChan;
|
||||
wifi_second_chan_t secondChan;
|
||||
esp_wifi_get_channel(&primaryChan, &secondChan);
|
||||
return primaryChan;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* store WiFi config in SDK flash area
|
||||
* @param persistent
|
||||
*/
|
||||
void WiFiGenericClass::persistent(bool persistent)
|
||||
{
|
||||
_persistent = persistent;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* set new mode
|
||||
* @param m WiFiMode_t
|
||||
*/
|
||||
bool WiFiGenericClass::mode(wifi_mode_t m)
|
||||
{
|
||||
wifi_mode_t cm = getMode();
|
||||
if(cm == WIFI_MODE_MAX){
|
||||
return false;
|
||||
}
|
||||
if(cm == m) {
|
||||
return true;
|
||||
}
|
||||
esp_err_t err;
|
||||
err = esp_wifi_set_mode(m);
|
||||
if(err){
|
||||
log_e("Could not set mode! %u", err);
|
||||
return false;
|
||||
}
|
||||
if(m){
|
||||
return espWiFiStart();
|
||||
}
|
||||
return espWiFiStop();
|
||||
}
|
||||
|
||||
/**
|
||||
* get WiFi mode
|
||||
* @return WiFiMode
|
||||
*/
|
||||
wifi_mode_t WiFiGenericClass::getMode()
|
||||
{
|
||||
if(!wifiLowLevelInit()){
|
||||
return WIFI_MODE_MAX;
|
||||
}
|
||||
uint8_t mode;
|
||||
esp_wifi_get_mode((wifi_mode_t*)&mode);
|
||||
return (wifi_mode_t)mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* control STA mode
|
||||
* @param enable bool
|
||||
* @return ok
|
||||
*/
|
||||
bool WiFiGenericClass::enableSTA(bool enable)
|
||||
{
|
||||
|
||||
wifi_mode_t currentMode = getMode();
|
||||
bool isEnabled = ((currentMode & WIFI_MODE_STA) != 0);
|
||||
|
||||
if(isEnabled != enable) {
|
||||
if(enable) {
|
||||
return mode((wifi_mode_t)(currentMode | WIFI_MODE_STA));
|
||||
} else {
|
||||
return mode((wifi_mode_t)(currentMode & (~WIFI_MODE_STA)));
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* control AP mode
|
||||
* @param enable bool
|
||||
* @return ok
|
||||
*/
|
||||
bool WiFiGenericClass::enableAP(bool enable)
|
||||
{
|
||||
|
||||
wifi_mode_t currentMode = getMode();
|
||||
bool isEnabled = ((currentMode & WIFI_MODE_AP) != 0);
|
||||
|
||||
if(isEnabled != enable) {
|
||||
if(enable) {
|
||||
return mode((wifi_mode_t)(currentMode | WIFI_MODE_AP));
|
||||
} else {
|
||||
return mode((wifi_mode_t)(currentMode & (~WIFI_MODE_AP)));
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------ Generic Network function ---------------------------------------------
|
||||
// -----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
static bool _dns_busy = false;
|
||||
|
||||
/**
|
||||
* DNS callback
|
||||
* @param name
|
||||
* @param ipaddr
|
||||
* @param callback_arg
|
||||
*/
|
||||
static void wifi_dns_found_callback(const char *name, const ip_addr_t *ipaddr, void *callback_arg)
|
||||
{
|
||||
if(ipaddr) {
|
||||
(*reinterpret_cast<IPAddress*>(callback_arg)) = ipaddr->u_addr.ip4.addr;
|
||||
}
|
||||
_dns_busy = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the given hostname to an IP address.
|
||||
* @param aHostname Name to be resolved
|
||||
* @param aResult IPAddress structure to store the returned IP address
|
||||
* @return 1 if aIPAddrString was successfully converted to an IP address,
|
||||
* else error code
|
||||
*/
|
||||
int WiFiGenericClass::hostByName(const char* aHostname, IPAddress& aResult)
|
||||
{
|
||||
ip_addr_t addr;
|
||||
aResult = static_cast<uint32_t>(0);
|
||||
|
||||
_dns_busy = true;
|
||||
err_t err = dns_gethostbyname(aHostname, &addr, &wifi_dns_found_callback, &aResult);
|
||||
if(err == ERR_OK && addr.u_addr.ip4.addr) {
|
||||
aResult = addr.u_addr.ip4.addr;
|
||||
_dns_busy = false;
|
||||
} else if(err == ERR_INPROGRESS) {
|
||||
while(_dns_busy){
|
||||
delay(1);
|
||||
}
|
||||
} else {
|
||||
_dns_busy = false;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
ESP8266WiFiGeneric.cpp - WiFi library for esp8266
|
||||
|
||||
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
|
||||
This file is part of the esp8266 core for Arduino environment.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Reworked on 28 Dec 2015 by Markus Sattler
|
||||
|
||||
*/
|
||||
|
||||
#include "WiFi.h"
|
||||
#include "WiFiGeneric.h"
|
||||
|
||||
extern "C" {
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <esp_err.h>
|
||||
#include <esp_wifi.h>
|
||||
#include <esp_event_loop.h>
|
||||
#include "lwip/ip_addr.h"
|
||||
#include "lwip/opt.h"
|
||||
#include "lwip/err.h"
|
||||
#include "lwip/dns.h"
|
||||
#include "esp_ipc.h"
|
||||
|
||||
|
||||
} //extern "C"
|
||||
|
||||
#include "esp32-hal-log.h"
|
||||
|
||||
#undef min
|
||||
#undef max
|
||||
#include <vector>
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#if CONFIG_FREERTOS_UNICORE
|
||||
#define ARDUINO_RUNNING_CORE 0
|
||||
#else
|
||||
#define ARDUINO_RUNNING_CORE 1
|
||||
#endif
|
||||
|
||||
static xQueueHandle _network_event_queue;
|
||||
static TaskHandle_t _network_event_task_handle = NULL;
|
||||
|
||||
static void _network_event_task(void * arg){
|
||||
system_event_t *event = NULL;
|
||||
for (;;) {
|
||||
if(xQueueReceive(_network_event_queue, &event, portMAX_DELAY) == pdTRUE){
|
||||
WiFiGenericClass::_eventCallback(arg, event);
|
||||
}
|
||||
}
|
||||
vTaskDelete(NULL);
|
||||
_network_event_task_handle = NULL;
|
||||
}
|
||||
|
||||
static esp_err_t _network_event_cb(void *arg, system_event_t *event){
|
||||
if (xQueueSend(_network_event_queue, &event, portMAX_DELAY) != pdPASS) {
|
||||
log_w("Network Event Queue Send Failed!");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void _start_network_event_task(){
|
||||
if(!_network_event_queue){
|
||||
_network_event_queue = xQueueCreate(32, sizeof(system_event_t *));
|
||||
if(!_network_event_queue){
|
||||
log_e("Network Event Queue Create Failed!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(!_network_event_task_handle){
|
||||
xTaskCreatePinnedToCore(_network_event_task, "network_event", 4096, NULL, 2, &_network_event_task_handle, ARDUINO_RUNNING_CORE);
|
||||
if(!_network_event_task_handle){
|
||||
log_e("Network Event Task Start Failed!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
esp_event_loop_init(&_network_event_cb, NULL);
|
||||
}
|
||||
|
||||
void tcpipInit(){
|
||||
static bool initialized = false;
|
||||
if(!initialized){
|
||||
initialized = true;
|
||||
_start_network_event_task();
|
||||
tcpip_adapter_init();
|
||||
}
|
||||
}
|
||||
|
||||
static bool wifiLowLevelInit(){
|
||||
static bool lowLevelInitDone = false;
|
||||
if(!lowLevelInitDone){
|
||||
tcpipInit();
|
||||
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
||||
esp_err_t err = esp_wifi_init(&cfg);
|
||||
if(err){
|
||||
log_e("esp_wifi_init %d", err);
|
||||
return false;
|
||||
}
|
||||
esp_wifi_set_storage(WIFI_STORAGE_FLASH);
|
||||
esp_wifi_set_mode(WIFI_MODE_NULL);
|
||||
lowLevelInitDone = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool wifiLowLevelDeinit(){
|
||||
//deinit not working yet!
|
||||
//esp_wifi_deinit();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _esp_wifi_started = false;
|
||||
|
||||
static bool espWiFiStart(){
|
||||
if(_esp_wifi_started){
|
||||
return true;
|
||||
}
|
||||
if(!wifiLowLevelInit()){
|
||||
return false;
|
||||
}
|
||||
esp_err_t err = esp_wifi_start();
|
||||
if (err != ESP_OK) {
|
||||
log_e("esp_wifi_start %d", err);
|
||||
wifiLowLevelDeinit();
|
||||
return false;
|
||||
}
|
||||
_esp_wifi_started = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool espWiFiStop(){
|
||||
esp_err_t err;
|
||||
if(!_esp_wifi_started){
|
||||
return true;
|
||||
}
|
||||
err = esp_wifi_stop();
|
||||
if(err){
|
||||
log_e("Could not stop WiFi! %u", err);
|
||||
return false;
|
||||
}
|
||||
_esp_wifi_started = false;
|
||||
return wifiLowLevelDeinit();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------- Generic WiFi function -----------------------------------------------
|
||||
// -----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
typedef struct {
|
||||
WiFiEventCb cb;
|
||||
WiFiEventFullCb fcb;
|
||||
WiFiEventSysCb scb;
|
||||
system_event_id_t event;
|
||||
} WiFiEventCbList_t;
|
||||
|
||||
// arduino dont like std::vectors move static here
|
||||
static std::vector<WiFiEventCbList_t> cbEventList;
|
||||
|
||||
bool WiFiGenericClass::_persistent = true;
|
||||
wifi_mode_t WiFiGenericClass::_forceSleepLastMode = WIFI_MODE_NULL;
|
||||
|
||||
WiFiGenericClass::WiFiGenericClass()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* set callback function
|
||||
* @param cbEvent WiFiEventCb
|
||||
* @param event optional filter (WIFI_EVENT_MAX is all events)
|
||||
*/
|
||||
void WiFiGenericClass::onEvent(WiFiEventCb cbEvent, system_event_id_t event)
|
||||
{
|
||||
if(!cbEvent) {
|
||||
return;
|
||||
}
|
||||
WiFiEventCbList_t newEventHandler;
|
||||
newEventHandler.cb = cbEvent;
|
||||
newEventHandler.fcb = NULL;
|
||||
newEventHandler.scb = NULL;
|
||||
newEventHandler.event = event;
|
||||
cbEventList.push_back(newEventHandler);
|
||||
}
|
||||
|
||||
void WiFiGenericClass::onEvent(WiFiEventFullCb cbEvent, system_event_id_t event)
|
||||
{
|
||||
if(!cbEvent) {
|
||||
return;
|
||||
}
|
||||
WiFiEventCbList_t newEventHandler;
|
||||
newEventHandler.cb = NULL;
|
||||
newEventHandler.fcb = cbEvent;
|
||||
newEventHandler.scb = NULL;
|
||||
newEventHandler.event = event;
|
||||
cbEventList.push_back(newEventHandler);
|
||||
}
|
||||
|
||||
void WiFiGenericClass::onEvent(WiFiEventSysCb cbEvent, system_event_id_t event)
|
||||
{
|
||||
if(!cbEvent) {
|
||||
return;
|
||||
}
|
||||
WiFiEventCbList_t newEventHandler;
|
||||
newEventHandler.cb = NULL;
|
||||
newEventHandler.fcb = NULL;
|
||||
newEventHandler.scb = cbEvent;
|
||||
newEventHandler.event = event;
|
||||
cbEventList.push_back(newEventHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* removes a callback form event handler
|
||||
* @param cbEvent WiFiEventCb
|
||||
* @param event optional filter (WIFI_EVENT_MAX is all events)
|
||||
*/
|
||||
void WiFiGenericClass::removeEvent(WiFiEventCb cbEvent, system_event_id_t event)
|
||||
{
|
||||
if(!cbEvent) {
|
||||
return;
|
||||
}
|
||||
|
||||
for(uint32_t i = 0; i < cbEventList.size(); i++) {
|
||||
WiFiEventCbList_t entry = cbEventList[i];
|
||||
if(entry.cb == cbEvent && entry.event == event) {
|
||||
cbEventList.erase(cbEventList.begin() + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WiFiGenericClass::removeEvent(WiFiEventFullCb cbEvent, system_event_id_t event)
|
||||
{
|
||||
if(!cbEvent) {
|
||||
return;
|
||||
}
|
||||
|
||||
for(uint32_t i = 0; i < cbEventList.size(); i++) {
|
||||
WiFiEventCbList_t entry = cbEventList[i];
|
||||
if(entry.fcb == cbEvent && entry.event == event) {
|
||||
cbEventList.erase(cbEventList.begin() + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WiFiGenericClass::removeEvent(WiFiEventSysCb cbEvent, system_event_id_t event)
|
||||
{
|
||||
if(!cbEvent) {
|
||||
return;
|
||||
}
|
||||
|
||||
for(uint32_t i = 0; i < cbEventList.size(); i++) {
|
||||
WiFiEventCbList_t entry = cbEventList[i];
|
||||
if(entry.scb == cbEvent && entry.event == event) {
|
||||
cbEventList.erase(cbEventList.begin() + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* callback for WiFi events
|
||||
* @param arg
|
||||
*/
|
||||
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_DEBUG
|
||||
const char * system_event_names[] = { "WIFI_READY", "SCAN_DONE", "STA_START", "STA_STOP", "STA_CONNECTED", "STA_DISCONNECTED", "STA_AUTHMODE_CHANGE", "STA_GOT_IP", "STA_LOST_IP", "STA_WPS_ER_SUCCESS", "STA_WPS_ER_FAILED", "STA_WPS_ER_TIMEOUT", "STA_WPS_ER_PIN", "AP_START", "AP_STOP", "AP_STACONNECTED", "AP_STADISCONNECTED", "AP_PROBEREQRECVED", "GOT_IP6", "ETH_START", "ETH_STOP", "ETH_CONNECTED", "ETH_DISCONNECTED", "ETH_GOT_IP", "MAX"};
|
||||
#endif
|
||||
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_WARN
|
||||
const char * system_event_reasons[] = { "UNSPECIFIED", "AUTH_EXPIRE", "AUTH_LEAVE", "ASSOC_EXPIRE", "ASSOC_TOOMANY", "NOT_AUTHED", "NOT_ASSOCED", "ASSOC_LEAVE", "ASSOC_NOT_AUTHED", "DISASSOC_PWRCAP_BAD", "DISASSOC_SUPCHAN_BAD", "IE_INVALID", "MIC_FAILURE", "4WAY_HANDSHAKE_TIMEOUT", "GROUP_KEY_UPDATE_TIMEOUT", "IE_IN_4WAY_DIFFERS", "GROUP_CIPHER_INVALID", "PAIRWISE_CIPHER_INVALID", "AKMP_INVALID", "UNSUPP_RSN_IE_VERSION", "INVALID_RSN_IE_CAP", "802_1X_AUTH_FAILED", "CIPHER_SUITE_REJECTED", "BEACON_TIMEOUT", "NO_AP_FOUND", "AUTH_FAIL", "ASSOC_FAIL", "HANDSHAKE_TIMEOUT" };
|
||||
#define reason2str(r) ((r>176)?system_event_reasons[r-177]:system_event_reasons[r-1])
|
||||
#endif
|
||||
esp_err_t WiFiGenericClass::_eventCallback(void *arg, system_event_t *event)
|
||||
{
|
||||
log_d("Event: %d - %s", event->event_id, system_event_names[event->event_id]);
|
||||
if(event->event_id == SYSTEM_EVENT_SCAN_DONE) {
|
||||
WiFiScanClass::_scanDone();
|
||||
} else if(event->event_id == SYSTEM_EVENT_STA_DISCONNECTED) {
|
||||
uint8_t reason = event->event_info.disconnected.reason;
|
||||
log_w("Reason: %u - %s", reason, reason2str(reason));
|
||||
if(reason == WIFI_REASON_NO_AP_FOUND) {
|
||||
WiFiSTAClass::_setStatus(WL_NO_SSID_AVAIL);
|
||||
} else if(reason == WIFI_REASON_AUTH_FAIL || reason == WIFI_REASON_ASSOC_FAIL) {
|
||||
WiFiSTAClass::_setStatus(WL_CONNECT_FAILED);
|
||||
} else if(reason == WIFI_REASON_BEACON_TIMEOUT || reason == WIFI_REASON_HANDSHAKE_TIMEOUT) {
|
||||
WiFiSTAClass::_setStatus(WL_CONNECTION_LOST);
|
||||
} else if(reason == WIFI_REASON_AUTH_EXPIRE) {
|
||||
if(WiFi.getAutoReconnect()){
|
||||
WiFi.begin();
|
||||
}
|
||||
} else {
|
||||
WiFiSTAClass::_setStatus(WL_DISCONNECTED);
|
||||
}
|
||||
} else if(event->event_id == SYSTEM_EVENT_STA_START) {
|
||||
WiFiSTAClass::_setStatus(WL_DISCONNECTED);
|
||||
} else if(event->event_id == SYSTEM_EVENT_STA_STOP) {
|
||||
WiFiSTAClass::_setStatus(WL_NO_SHIELD);
|
||||
} else if(event->event_id == SYSTEM_EVENT_STA_CONNECTED) {
|
||||
WiFiSTAClass::_setStatus(WL_IDLE_STATUS);
|
||||
} else if(event->event_id == SYSTEM_EVENT_STA_GOT_IP) {
|
||||
//#1081 https://github.com/espressif/arduino-esp32/issues/1081
|
||||
// if(WiFiSTAClass::status() == WL_IDLE_STATUS)
|
||||
{
|
||||
WiFiSTAClass::_setStatus(WL_CONNECTED);
|
||||
}
|
||||
}
|
||||
|
||||
for(uint32_t i = 0; i < cbEventList.size(); i++) {
|
||||
WiFiEventCbList_t entry = cbEventList[i];
|
||||
if(entry.cb || entry.fcb || entry.scb) {
|
||||
if(entry.event == (system_event_id_t) event->event_id || entry.event == SYSTEM_EVENT_MAX) {
|
||||
if(entry.cb){
|
||||
entry.cb((system_event_id_t) event->event_id);
|
||||
} else if(entry.fcb){
|
||||
entry.fcb((system_event_id_t) event->event_id, (system_event_info_t) event->event_info);
|
||||
} else {
|
||||
entry.scb(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current channel associated with the network
|
||||
* @return channel (1-13)
|
||||
*/
|
||||
int32_t WiFiGenericClass::channel(void)
|
||||
{
|
||||
uint8_t primaryChan;
|
||||
wifi_second_chan_t secondChan;
|
||||
esp_wifi_get_channel(&primaryChan, &secondChan);
|
||||
return primaryChan;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* store WiFi config in SDK flash area
|
||||
* @param persistent
|
||||
*/
|
||||
void WiFiGenericClass::persistent(bool persistent)
|
||||
{
|
||||
_persistent = persistent;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* set new mode
|
||||
* @param m WiFiMode_t
|
||||
*/
|
||||
bool WiFiGenericClass::mode(wifi_mode_t m)
|
||||
{
|
||||
wifi_mode_t cm = getMode();
|
||||
if(cm == WIFI_MODE_MAX){
|
||||
return false;
|
||||
}
|
||||
if(cm == m) {
|
||||
return true;
|
||||
}
|
||||
esp_err_t err;
|
||||
err = esp_wifi_set_mode(m);
|
||||
if(err){
|
||||
log_e("Could not set mode! %u", err);
|
||||
return false;
|
||||
}
|
||||
if(m){
|
||||
return espWiFiStart();
|
||||
}
|
||||
return espWiFiStop();
|
||||
}
|
||||
|
||||
/**
|
||||
* get WiFi mode
|
||||
* @return WiFiMode
|
||||
*/
|
||||
wifi_mode_t WiFiGenericClass::getMode()
|
||||
{
|
||||
if(!wifiLowLevelInit()){
|
||||
return WIFI_MODE_MAX;
|
||||
}
|
||||
uint8_t mode;
|
||||
esp_wifi_get_mode((wifi_mode_t*)&mode);
|
||||
return (wifi_mode_t)mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* control STA mode
|
||||
* @param enable bool
|
||||
* @return ok
|
||||
*/
|
||||
bool WiFiGenericClass::enableSTA(bool enable)
|
||||
{
|
||||
|
||||
wifi_mode_t currentMode = getMode();
|
||||
bool isEnabled = ((currentMode & WIFI_MODE_STA) != 0);
|
||||
|
||||
if(isEnabled != enable) {
|
||||
if(enable) {
|
||||
return mode((wifi_mode_t)(currentMode | WIFI_MODE_STA));
|
||||
} else {
|
||||
return mode((wifi_mode_t)(currentMode & (~WIFI_MODE_STA)));
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* control AP mode
|
||||
* @param enable bool
|
||||
* @return ok
|
||||
*/
|
||||
bool WiFiGenericClass::enableAP(bool enable)
|
||||
{
|
||||
|
||||
wifi_mode_t currentMode = getMode();
|
||||
bool isEnabled = ((currentMode & WIFI_MODE_AP) != 0);
|
||||
|
||||
if(isEnabled != enable) {
|
||||
if(enable) {
|
||||
return mode((wifi_mode_t)(currentMode | WIFI_MODE_AP));
|
||||
} else {
|
||||
return mode((wifi_mode_t)(currentMode & (~WIFI_MODE_AP)));
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------ Generic Network function ---------------------------------------------
|
||||
// -----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
static bool _dns_busy = false;
|
||||
|
||||
/**
|
||||
* DNS callback
|
||||
* @param name
|
||||
* @param ipaddr
|
||||
* @param callback_arg
|
||||
*/
|
||||
static void wifi_dns_found_callback(const char *name, const ip_addr_t *ipaddr, void *callback_arg)
|
||||
{
|
||||
if(ipaddr) {
|
||||
(*reinterpret_cast<IPAddress*>(callback_arg)) = ipaddr->u_addr.ip4.addr;
|
||||
}
|
||||
_dns_busy = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the given hostname to an IP address.
|
||||
* @param aHostname Name to be resolved
|
||||
* @param aResult IPAddress structure to store the returned IP address
|
||||
* @return 1 if aIPAddrString was successfully converted to an IP address,
|
||||
* else error code
|
||||
*/
|
||||
int WiFiGenericClass::hostByName(const char* aHostname, IPAddress& aResult)
|
||||
{
|
||||
ip_addr_t addr;
|
||||
aResult = static_cast<uint32_t>(0);
|
||||
|
||||
_dns_busy = true;
|
||||
err_t err = dns_gethostbyname(aHostname, &addr, &wifi_dns_found_callback, &aResult);
|
||||
if(err == ERR_OK && addr.u_addr.ip4.addr) {
|
||||
aResult = addr.u_addr.ip4.addr;
|
||||
_dns_busy = false;
|
||||
} else if(err == ERR_INPROGRESS) {
|
||||
while(_dns_busy){
|
||||
delay(1);
|
||||
}
|
||||
} else {
|
||||
_dns_busy = false;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1,74 +1,74 @@
|
||||
/*
|
||||
ESP8266WiFiGeneric.h - esp8266 Wifi support.
|
||||
Based on WiFi.h from Ardiono WiFi shield library.
|
||||
Copyright (c) 2011-2014 Arduino. All right reserved.
|
||||
Modified by Ivan Grokhotkov, December 2014
|
||||
Reworked by Markus Sattler, December 2015
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef ESP32WIFIGENERIC_H_
|
||||
#define ESP32WIFIGENERIC_H_
|
||||
|
||||
#include "WiFiType.h"
|
||||
#include <esp_err.h>
|
||||
#include <esp_event_loop.h>
|
||||
|
||||
typedef void (*WiFiEventCb)(system_event_id_t event);
|
||||
typedef void (*WiFiEventFullCb)(system_event_id_t event, system_event_info_t info);
|
||||
typedef void (*WiFiEventSysCb)(system_event_t *event);
|
||||
|
||||
class WiFiGenericClass
|
||||
{
|
||||
public:
|
||||
|
||||
WiFiGenericClass();
|
||||
|
||||
void onEvent(WiFiEventCb cbEvent, system_event_id_t event = SYSTEM_EVENT_MAX);
|
||||
void onEvent(WiFiEventFullCb cbEvent, system_event_id_t event = SYSTEM_EVENT_MAX);
|
||||
void onEvent(WiFiEventSysCb cbEvent, system_event_id_t event = SYSTEM_EVENT_MAX);
|
||||
void removeEvent(WiFiEventCb cbEvent, system_event_id_t event = SYSTEM_EVENT_MAX);
|
||||
void removeEvent(WiFiEventFullCb cbEvent, system_event_id_t event = SYSTEM_EVENT_MAX);
|
||||
void removeEvent(WiFiEventSysCb cbEvent, system_event_id_t event = SYSTEM_EVENT_MAX);
|
||||
|
||||
int32_t channel(void);
|
||||
|
||||
void persistent(bool persistent);
|
||||
|
||||
static bool mode(wifi_mode_t);
|
||||
static wifi_mode_t getMode();
|
||||
|
||||
bool enableSTA(bool enable);
|
||||
bool enableAP(bool enable);
|
||||
|
||||
static esp_err_t _eventCallback(void *arg, system_event_t *event);
|
||||
|
||||
protected:
|
||||
static bool _persistent;
|
||||
static wifi_mode_t _forceSleepLastMode;
|
||||
|
||||
public:
|
||||
|
||||
int hostByName(const char* aHostname, IPAddress& aResult);
|
||||
|
||||
protected:
|
||||
|
||||
friend class WiFiSTAClass;
|
||||
friend class WiFiScanClass;
|
||||
friend class WiFiAPClass;
|
||||
};
|
||||
|
||||
#endif /* ESP32WIFIGENERIC_H_ */
|
||||
/*
|
||||
ESP8266WiFiGeneric.h - esp8266 Wifi support.
|
||||
Based on WiFi.h from Ardiono WiFi shield library.
|
||||
Copyright (c) 2011-2014 Arduino. All right reserved.
|
||||
Modified by Ivan Grokhotkov, December 2014
|
||||
Reworked by Markus Sattler, December 2015
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef ESP32WIFIGENERIC_H_
|
||||
#define ESP32WIFIGENERIC_H_
|
||||
|
||||
#include "WiFiType.h"
|
||||
#include <esp_err.h>
|
||||
#include <esp_event_loop.h>
|
||||
|
||||
typedef void (*WiFiEventCb)(system_event_id_t event);
|
||||
typedef void (*WiFiEventFullCb)(system_event_id_t event, system_event_info_t info);
|
||||
typedef void (*WiFiEventSysCb)(system_event_t *event);
|
||||
|
||||
class WiFiGenericClass
|
||||
{
|
||||
public:
|
||||
|
||||
WiFiGenericClass();
|
||||
|
||||
void onEvent(WiFiEventCb cbEvent, system_event_id_t event = SYSTEM_EVENT_MAX);
|
||||
void onEvent(WiFiEventFullCb cbEvent, system_event_id_t event = SYSTEM_EVENT_MAX);
|
||||
void onEvent(WiFiEventSysCb cbEvent, system_event_id_t event = SYSTEM_EVENT_MAX);
|
||||
void removeEvent(WiFiEventCb cbEvent, system_event_id_t event = SYSTEM_EVENT_MAX);
|
||||
void removeEvent(WiFiEventFullCb cbEvent, system_event_id_t event = SYSTEM_EVENT_MAX);
|
||||
void removeEvent(WiFiEventSysCb cbEvent, system_event_id_t event = SYSTEM_EVENT_MAX);
|
||||
|
||||
int32_t channel(void);
|
||||
|
||||
void persistent(bool persistent);
|
||||
|
||||
static bool mode(wifi_mode_t);
|
||||
static wifi_mode_t getMode();
|
||||
|
||||
bool enableSTA(bool enable);
|
||||
bool enableAP(bool enable);
|
||||
|
||||
static esp_err_t _eventCallback(void *arg, system_event_t *event);
|
||||
|
||||
protected:
|
||||
static bool _persistent;
|
||||
static wifi_mode_t _forceSleepLastMode;
|
||||
|
||||
public:
|
||||
|
||||
int hostByName(const char* aHostname, IPAddress& aResult);
|
||||
|
||||
protected:
|
||||
|
||||
friend class WiFiSTAClass;
|
||||
friend class WiFiScanClass;
|
||||
friend class WiFiAPClass;
|
||||
};
|
||||
|
||||
#endif /* ESP32WIFIGENERIC_H_ */
|
||||
|
@ -1,219 +1,219 @@
|
||||
/**
|
||||
*
|
||||
* @file ESP8266WiFiMulti.cpp
|
||||
* @date 16.05.2015
|
||||
* @author Markus Sattler
|
||||
*
|
||||
* Copyright (c) 2015 Markus Sattler. All rights reserved.
|
||||
* This file is part of the esp8266 core for Arduino environment.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "WiFiMulti.h"
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <esp32-hal.h>
|
||||
|
||||
WiFiMulti::WiFiMulti()
|
||||
{
|
||||
}
|
||||
|
||||
WiFiMulti::~WiFiMulti()
|
||||
{
|
||||
APlistClean();
|
||||
}
|
||||
|
||||
bool WiFiMulti::addAP(const char* ssid, const char *passphrase)
|
||||
{
|
||||
return APlistAdd(ssid, passphrase);
|
||||
}
|
||||
|
||||
uint8_t WiFiMulti::run(uint32_t connectTimeout)
|
||||
{
|
||||
|
||||
int8_t scanResult;
|
||||
uint8_t status = WiFi.status();
|
||||
if(status != WL_CONNECTED || status == WL_NO_SSID_AVAIL || status == WL_IDLE_STATUS || status == WL_CONNECT_FAILED) {
|
||||
|
||||
scanResult = WiFi.scanNetworks();
|
||||
if(scanResult == WIFI_SCAN_RUNNING) {
|
||||
// scan is running
|
||||
return WL_NO_SSID_AVAIL;
|
||||
} else if(scanResult > 0) {
|
||||
// scan done analyze
|
||||
WifiAPlist_t bestNetwork { NULL, NULL };
|
||||
int bestNetworkDb = INT_MIN;
|
||||
uint8_t bestBSSID[6];
|
||||
int32_t bestChannel = 0;
|
||||
|
||||
DEBUG_WIFI_MULTI("[WIFI] scan done\n");
|
||||
delay(0);
|
||||
|
||||
if(scanResult <= 0) {
|
||||
DEBUG_WIFI_MULTI("[WIFI] no networks found\n");
|
||||
} else {
|
||||
DEBUG_WIFI_MULTI("[WIFI] %d networks found\n", scanResult);
|
||||
for(int8_t i = 0; i < scanResult; ++i) {
|
||||
|
||||
String ssid_scan;
|
||||
int32_t rssi_scan;
|
||||
uint8_t sec_scan;
|
||||
uint8_t* BSSID_scan;
|
||||
int32_t chan_scan;
|
||||
|
||||
WiFi.getNetworkInfo(i, ssid_scan, sec_scan, rssi_scan, BSSID_scan, chan_scan);
|
||||
|
||||
bool known = false;
|
||||
for(uint32_t x = 0; x < APlist.size(); x++) {
|
||||
WifiAPlist_t entry = APlist[x];
|
||||
|
||||
if(ssid_scan == entry.ssid) { // SSID match
|
||||
known = true;
|
||||
if(rssi_scan > bestNetworkDb) { // best network
|
||||
if(sec_scan == WIFI_AUTH_OPEN || entry.passphrase) { // check for passphrase if not open wlan
|
||||
bestNetworkDb = rssi_scan;
|
||||
bestChannel = chan_scan;
|
||||
memcpy((void*) &bestNetwork, (void*) &entry, sizeof(bestNetwork));
|
||||
memcpy((void*) &bestBSSID, (void*) BSSID_scan, sizeof(bestBSSID));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(known) {
|
||||
DEBUG_WIFI_MULTI(" ---> ");
|
||||
} else {
|
||||
DEBUG_WIFI_MULTI(" ");
|
||||
}
|
||||
|
||||
DEBUG_WIFI_MULTI(" %d: [%d][%02X:%02X:%02X:%02X:%02X:%02X] %s (%d) %c\n", i, chan_scan, BSSID_scan[0], BSSID_scan[1], BSSID_scan[2], BSSID_scan[3], BSSID_scan[4], BSSID_scan[5], ssid_scan.c_str(), rssi_scan, (sec_scan == WIFI_AUTH_OPEN) ? ' ' : '*');
|
||||
delay(0);
|
||||
}
|
||||
}
|
||||
|
||||
// clean up ram
|
||||
WiFi.scanDelete();
|
||||
|
||||
DEBUG_WIFI_MULTI("\n\n");
|
||||
delay(0);
|
||||
|
||||
if(bestNetwork.ssid) {
|
||||
DEBUG_WIFI_MULTI("[WIFI] Connecting BSSID: %02X:%02X:%02X:%02X:%02X:%02X SSID: %s Channal: %d (%d)\n", bestBSSID[0], bestBSSID[1], bestBSSID[2], bestBSSID[3], bestBSSID[4], bestBSSID[5], bestNetwork.ssid, bestChannel, bestNetworkDb);
|
||||
|
||||
WiFi.begin(bestNetwork.ssid, bestNetwork.passphrase, bestChannel, bestBSSID);
|
||||
status = WiFi.status();
|
||||
|
||||
auto startTime = millis();
|
||||
// wait for connection, fail, or timeout
|
||||
while(status != WL_CONNECTED && status != WL_NO_SSID_AVAIL && status != WL_CONNECT_FAILED && (millis() - startTime) <= connectTimeout) {
|
||||
delay(10);
|
||||
status = WiFi.status();
|
||||
}
|
||||
|
||||
IPAddress ip;
|
||||
uint8_t * mac;
|
||||
switch(status) {
|
||||
case 3:
|
||||
ip = WiFi.localIP();
|
||||
mac = WiFi.BSSID();
|
||||
DEBUG_WIFI_MULTI("[WIFI] Connecting done.\n");
|
||||
DEBUG_WIFI_MULTI("[WIFI] SSID: %s\n", WiFi.SSID());
|
||||
DEBUG_WIFI_MULTI("[WIFI] IP: %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]);
|
||||
DEBUG_WIFI_MULTI("[WIFI] MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
DEBUG_WIFI_MULTI("[WIFI] Channel: %d\n", WiFi.channel());
|
||||
break;
|
||||
case 1:
|
||||
DEBUG_WIFI_MULTI("[WIFI] Connecting Failed AP not found.\n");
|
||||
break;
|
||||
case 4:
|
||||
DEBUG_WIFI_MULTI("[WIFI] Connecting Failed.\n");
|
||||
break;
|
||||
default:
|
||||
DEBUG_WIFI_MULTI("[WIFI] Connecting Failed (%d).\n", status);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
DEBUG_WIFI_MULTI("[WIFI] no matching wifi found!\n");
|
||||
}
|
||||
} else {
|
||||
// start scan
|
||||
DEBUG_WIFI_MULTI("[WIFI] delete old wifi config...\n");
|
||||
WiFi.disconnect();
|
||||
|
||||
DEBUG_WIFI_MULTI("[WIFI] start scan\n");
|
||||
// scan wifi async mode
|
||||
WiFi.scanNetworks(true);
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
// ##################################################################################
|
||||
|
||||
bool WiFiMulti::APlistAdd(const char* ssid, const char *passphrase)
|
||||
{
|
||||
|
||||
WifiAPlist_t newAP;
|
||||
|
||||
if(!ssid || *ssid == 0x00 || strlen(ssid) > 31) {
|
||||
// fail SSID to long or missing!
|
||||
DEBUG_WIFI_MULTI("[WIFI][APlistAdd] no ssid or ssid to long\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(passphrase && strlen(passphrase) > 63) {
|
||||
// fail passphrase to long!
|
||||
DEBUG_WIFI_MULTI("[WIFI][APlistAdd] passphrase to long\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
newAP.ssid = strdup(ssid);
|
||||
|
||||
if(!newAP.ssid) {
|
||||
DEBUG_WIFI_MULTI("[WIFI][APlistAdd] fail newAP.ssid == 0\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(passphrase && *passphrase != 0x00) {
|
||||
newAP.passphrase = strdup(passphrase);
|
||||
if(!newAP.passphrase) {
|
||||
DEBUG_WIFI_MULTI("[WIFI][APlistAdd] fail newAP.passphrase == 0\n");
|
||||
free(newAP.ssid);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
APlist.push_back(newAP);
|
||||
DEBUG_WIFI_MULTI("[WIFI][APlistAdd] add SSID: %s\n", newAP.ssid);
|
||||
return true;
|
||||
}
|
||||
|
||||
void WiFiMulti::APlistClean(void)
|
||||
{
|
||||
for(uint32_t i = 0; i < APlist.size(); i++) {
|
||||
WifiAPlist_t entry = APlist[i];
|
||||
if(entry.ssid) {
|
||||
free(entry.ssid);
|
||||
}
|
||||
if(entry.passphrase) {
|
||||
free(entry.passphrase);
|
||||
}
|
||||
}
|
||||
APlist.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @file ESP8266WiFiMulti.cpp
|
||||
* @date 16.05.2015
|
||||
* @author Markus Sattler
|
||||
*
|
||||
* Copyright (c) 2015 Markus Sattler. All rights reserved.
|
||||
* This file is part of the esp8266 core for Arduino environment.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "WiFiMulti.h"
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <esp32-hal.h>
|
||||
|
||||
WiFiMulti::WiFiMulti()
|
||||
{
|
||||
}
|
||||
|
||||
WiFiMulti::~WiFiMulti()
|
||||
{
|
||||
APlistClean();
|
||||
}
|
||||
|
||||
bool WiFiMulti::addAP(const char* ssid, const char *passphrase)
|
||||
{
|
||||
return APlistAdd(ssid, passphrase);
|
||||
}
|
||||
|
||||
uint8_t WiFiMulti::run(uint32_t connectTimeout)
|
||||
{
|
||||
|
||||
int8_t scanResult;
|
||||
uint8_t status = WiFi.status();
|
||||
if(status != WL_CONNECTED || status == WL_NO_SSID_AVAIL || status == WL_IDLE_STATUS || status == WL_CONNECT_FAILED) {
|
||||
|
||||
scanResult = WiFi.scanNetworks();
|
||||
if(scanResult == WIFI_SCAN_RUNNING) {
|
||||
// scan is running
|
||||
return WL_NO_SSID_AVAIL;
|
||||
} else if(scanResult > 0) {
|
||||
// scan done analyze
|
||||
WifiAPlist_t bestNetwork { NULL, NULL };
|
||||
int bestNetworkDb = INT_MIN;
|
||||
uint8_t bestBSSID[6];
|
||||
int32_t bestChannel = 0;
|
||||
|
||||
DEBUG_WIFI_MULTI("[WIFI] scan done\n");
|
||||
delay(0);
|
||||
|
||||
if(scanResult <= 0) {
|
||||
DEBUG_WIFI_MULTI("[WIFI] no networks found\n");
|
||||
} else {
|
||||
DEBUG_WIFI_MULTI("[WIFI] %d networks found\n", scanResult);
|
||||
for(int8_t i = 0; i < scanResult; ++i) {
|
||||
|
||||
String ssid_scan;
|
||||
int32_t rssi_scan;
|
||||
uint8_t sec_scan;
|
||||
uint8_t* BSSID_scan;
|
||||
int32_t chan_scan;
|
||||
|
||||
WiFi.getNetworkInfo(i, ssid_scan, sec_scan, rssi_scan, BSSID_scan, chan_scan);
|
||||
|
||||
bool known = false;
|
||||
for(uint32_t x = 0; x < APlist.size(); x++) {
|
||||
WifiAPlist_t entry = APlist[x];
|
||||
|
||||
if(ssid_scan == entry.ssid) { // SSID match
|
||||
known = true;
|
||||
if(rssi_scan > bestNetworkDb) { // best network
|
||||
if(sec_scan == WIFI_AUTH_OPEN || entry.passphrase) { // check for passphrase if not open wlan
|
||||
bestNetworkDb = rssi_scan;
|
||||
bestChannel = chan_scan;
|
||||
memcpy((void*) &bestNetwork, (void*) &entry, sizeof(bestNetwork));
|
||||
memcpy((void*) &bestBSSID, (void*) BSSID_scan, sizeof(bestBSSID));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(known) {
|
||||
DEBUG_WIFI_MULTI(" ---> ");
|
||||
} else {
|
||||
DEBUG_WIFI_MULTI(" ");
|
||||
}
|
||||
|
||||
DEBUG_WIFI_MULTI(" %d: [%d][%02X:%02X:%02X:%02X:%02X:%02X] %s (%d) %c\n", i, chan_scan, BSSID_scan[0], BSSID_scan[1], BSSID_scan[2], BSSID_scan[3], BSSID_scan[4], BSSID_scan[5], ssid_scan.c_str(), rssi_scan, (sec_scan == WIFI_AUTH_OPEN) ? ' ' : '*');
|
||||
delay(0);
|
||||
}
|
||||
}
|
||||
|
||||
// clean up ram
|
||||
WiFi.scanDelete();
|
||||
|
||||
DEBUG_WIFI_MULTI("\n\n");
|
||||
delay(0);
|
||||
|
||||
if(bestNetwork.ssid) {
|
||||
DEBUG_WIFI_MULTI("[WIFI] Connecting BSSID: %02X:%02X:%02X:%02X:%02X:%02X SSID: %s Channal: %d (%d)\n", bestBSSID[0], bestBSSID[1], bestBSSID[2], bestBSSID[3], bestBSSID[4], bestBSSID[5], bestNetwork.ssid, bestChannel, bestNetworkDb);
|
||||
|
||||
WiFi.begin(bestNetwork.ssid, bestNetwork.passphrase, bestChannel, bestBSSID);
|
||||
status = WiFi.status();
|
||||
|
||||
auto startTime = millis();
|
||||
// wait for connection, fail, or timeout
|
||||
while(status != WL_CONNECTED && status != WL_NO_SSID_AVAIL && status != WL_CONNECT_FAILED && (millis() - startTime) <= connectTimeout) {
|
||||
delay(10);
|
||||
status = WiFi.status();
|
||||
}
|
||||
|
||||
IPAddress ip;
|
||||
uint8_t * mac;
|
||||
switch(status) {
|
||||
case 3:
|
||||
ip = WiFi.localIP();
|
||||
mac = WiFi.BSSID();
|
||||
DEBUG_WIFI_MULTI("[WIFI] Connecting done.\n");
|
||||
DEBUG_WIFI_MULTI("[WIFI] SSID: %s\n", WiFi.SSID());
|
||||
DEBUG_WIFI_MULTI("[WIFI] IP: %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]);
|
||||
DEBUG_WIFI_MULTI("[WIFI] MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
DEBUG_WIFI_MULTI("[WIFI] Channel: %d\n", WiFi.channel());
|
||||
break;
|
||||
case 1:
|
||||
DEBUG_WIFI_MULTI("[WIFI] Connecting Failed AP not found.\n");
|
||||
break;
|
||||
case 4:
|
||||
DEBUG_WIFI_MULTI("[WIFI] Connecting Failed.\n");
|
||||
break;
|
||||
default:
|
||||
DEBUG_WIFI_MULTI("[WIFI] Connecting Failed (%d).\n", status);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
DEBUG_WIFI_MULTI("[WIFI] no matching wifi found!\n");
|
||||
}
|
||||
} else {
|
||||
// start scan
|
||||
DEBUG_WIFI_MULTI("[WIFI] delete old wifi config...\n");
|
||||
WiFi.disconnect();
|
||||
|
||||
DEBUG_WIFI_MULTI("[WIFI] start scan\n");
|
||||
// scan wifi async mode
|
||||
WiFi.scanNetworks(true);
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
// ##################################################################################
|
||||
|
||||
bool WiFiMulti::APlistAdd(const char* ssid, const char *passphrase)
|
||||
{
|
||||
|
||||
WifiAPlist_t newAP;
|
||||
|
||||
if(!ssid || *ssid == 0x00 || strlen(ssid) > 31) {
|
||||
// fail SSID to long or missing!
|
||||
DEBUG_WIFI_MULTI("[WIFI][APlistAdd] no ssid or ssid to long\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(passphrase && strlen(passphrase) > 63) {
|
||||
// fail passphrase to long!
|
||||
DEBUG_WIFI_MULTI("[WIFI][APlistAdd] passphrase to long\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
newAP.ssid = strdup(ssid);
|
||||
|
||||
if(!newAP.ssid) {
|
||||
DEBUG_WIFI_MULTI("[WIFI][APlistAdd] fail newAP.ssid == 0\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(passphrase && *passphrase != 0x00) {
|
||||
newAP.passphrase = strdup(passphrase);
|
||||
if(!newAP.passphrase) {
|
||||
DEBUG_WIFI_MULTI("[WIFI][APlistAdd] fail newAP.passphrase == 0\n");
|
||||
free(newAP.ssid);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
APlist.push_back(newAP);
|
||||
DEBUG_WIFI_MULTI("[WIFI][APlistAdd] add SSID: %s\n", newAP.ssid);
|
||||
return true;
|
||||
}
|
||||
|
||||
void WiFiMulti::APlistClean(void)
|
||||
{
|
||||
for(uint32_t i = 0; i < APlist.size(); i++) {
|
||||
WifiAPlist_t entry = APlist[i];
|
||||
if(entry.ssid) {
|
||||
free(entry.ssid);
|
||||
}
|
||||
if(entry.passphrase) {
|
||||
free(entry.passphrase);
|
||||
}
|
||||
}
|
||||
APlist.clear();
|
||||
}
|
||||
|
||||
|
@ -1,66 +1,66 @@
|
||||
/**
|
||||
*
|
||||
* @file ESP8266WiFiMulti.h
|
||||
* @date 16.05.2015
|
||||
* @author Markus Sattler
|
||||
*
|
||||
* Copyright (c) 2015 Markus Sattler. All rights reserved.
|
||||
* This file is part of the esp8266 core for Arduino environment.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WIFICLIENTMULTI_H_
|
||||
#define WIFICLIENTMULTI_H_
|
||||
|
||||
#include "WiFi.h"
|
||||
#undef min
|
||||
#undef max
|
||||
#include <vector>
|
||||
|
||||
#ifdef DEBUG_ESP_WIFI
|
||||
#ifdef DEBUG_ESP_PORT
|
||||
#define DEBUG_WIFI_MULTI(...) DEBUG_ESP_PORT.printf( __VA_ARGS__ )
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef DEBUG_WIFI_MULTI
|
||||
#define DEBUG_WIFI_MULTI(...)
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
char * ssid;
|
||||
char * passphrase;
|
||||
} WifiAPlist_t;
|
||||
|
||||
class WiFiMulti
|
||||
{
|
||||
public:
|
||||
WiFiMulti();
|
||||
~WiFiMulti();
|
||||
|
||||
bool addAP(const char* ssid, const char *passphrase = NULL);
|
||||
|
||||
uint8_t run(uint32_t connectTimeout=5000);
|
||||
|
||||
private:
|
||||
std::vector<WifiAPlist_t> APlist;
|
||||
bool APlistAdd(const char* ssid, const char *passphrase = NULL);
|
||||
void APlistClean(void);
|
||||
|
||||
};
|
||||
|
||||
#endif /* WIFICLIENTMULTI_H_ */
|
||||
/**
|
||||
*
|
||||
* @file ESP8266WiFiMulti.h
|
||||
* @date 16.05.2015
|
||||
* @author Markus Sattler
|
||||
*
|
||||
* Copyright (c) 2015 Markus Sattler. All rights reserved.
|
||||
* This file is part of the esp8266 core for Arduino environment.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WIFICLIENTMULTI_H_
|
||||
#define WIFICLIENTMULTI_H_
|
||||
|
||||
#include "WiFi.h"
|
||||
#undef min
|
||||
#undef max
|
||||
#include <vector>
|
||||
|
||||
#ifdef DEBUG_ESP_WIFI
|
||||
#ifdef DEBUG_ESP_PORT
|
||||
#define DEBUG_WIFI_MULTI(...) DEBUG_ESP_PORT.printf( __VA_ARGS__ )
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef DEBUG_WIFI_MULTI
|
||||
#define DEBUG_WIFI_MULTI(...)
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
char * ssid;
|
||||
char * passphrase;
|
||||
} WifiAPlist_t;
|
||||
|
||||
class WiFiMulti
|
||||
{
|
||||
public:
|
||||
WiFiMulti();
|
||||
~WiFiMulti();
|
||||
|
||||
bool addAP(const char* ssid, const char *passphrase = NULL);
|
||||
|
||||
uint8_t run(uint32_t connectTimeout=5000);
|
||||
|
||||
private:
|
||||
std::vector<WifiAPlist_t> APlist;
|
||||
bool APlistAdd(const char* ssid, const char *passphrase = NULL);
|
||||
void APlistClean(void);
|
||||
|
||||
};
|
||||
|
||||
#endif /* WIFICLIENTMULTI_H_ */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,103 +1,103 @@
|
||||
/*
|
||||
ESP8266WiFiSTA.h - esp8266 Wifi support.
|
||||
Based on WiFi.h from Ardiono WiFi shield library.
|
||||
Copyright (c) 2011-2014 Arduino. All right reserved.
|
||||
Modified by Ivan Grokhotkov, December 2014
|
||||
Reworked by Markus Sattler, December 2015
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef ESP32WIFISTA_H_
|
||||
#define ESP32WIFISTA_H_
|
||||
|
||||
|
||||
#include "WiFiType.h"
|
||||
#include "WiFiGeneric.h"
|
||||
|
||||
|
||||
class WiFiSTAClass
|
||||
{
|
||||
// ----------------------------------------------------------------------------------------------
|
||||
// ---------------------------------------- STA function ----------------------------------------
|
||||
// ----------------------------------------------------------------------------------------------
|
||||
|
||||
public:
|
||||
|
||||
wl_status_t begin(const char* ssid, const char *passphrase = NULL, int32_t channel = 0, const uint8_t* bssid = NULL, bool connect = true);
|
||||
wl_status_t begin(char* ssid, char *passphrase = NULL, int32_t channel = 0, const uint8_t* bssid = NULL, bool connect = true);
|
||||
wl_status_t begin();
|
||||
|
||||
bool config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1 = (uint32_t)0x00000000, IPAddress dns2 = (uint32_t)0x00000000);
|
||||
|
||||
bool reconnect();
|
||||
bool disconnect(bool wifioff = false);
|
||||
|
||||
bool isConnected();
|
||||
|
||||
bool setAutoConnect(bool autoConnect);
|
||||
bool getAutoConnect();
|
||||
|
||||
bool setAutoReconnect(bool autoReconnect);
|
||||
bool getAutoReconnect();
|
||||
|
||||
uint8_t waitForConnectResult();
|
||||
|
||||
// STA network info
|
||||
IPAddress localIP();
|
||||
|
||||
uint8_t * macAddress(uint8_t* mac);
|
||||
String macAddress();
|
||||
|
||||
IPAddress subnetMask();
|
||||
IPAddress gatewayIP();
|
||||
IPAddress dnsIP(uint8_t dns_no = 0);
|
||||
|
||||
bool enableIpV6();
|
||||
IPv6Address localIPv6();
|
||||
|
||||
const char * getHostname();
|
||||
bool setHostname(const char * hostname);
|
||||
|
||||
// STA WiFi info
|
||||
static wl_status_t status();
|
||||
String SSID() const;
|
||||
String psk() const;
|
||||
|
||||
uint8_t * BSSID();
|
||||
String BSSIDstr();
|
||||
|
||||
int8_t RSSI();
|
||||
|
||||
static void _setStatus(wl_status_t status);
|
||||
protected:
|
||||
static wl_status_t _status;
|
||||
static bool _useStaticIp;
|
||||
static bool _autoReconnect;
|
||||
|
||||
public:
|
||||
bool beginSmartConfig();
|
||||
bool stopSmartConfig();
|
||||
bool smartConfigDone();
|
||||
|
||||
protected:
|
||||
static bool _smartConfigStarted;
|
||||
static bool _smartConfigDone;
|
||||
static void _smartConfigCallback(uint32_t status, void* result);
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif /* ESP32WIFISTA_H_ */
|
||||
/*
|
||||
ESP8266WiFiSTA.h - esp8266 Wifi support.
|
||||
Based on WiFi.h from Ardiono WiFi shield library.
|
||||
Copyright (c) 2011-2014 Arduino. All right reserved.
|
||||
Modified by Ivan Grokhotkov, December 2014
|
||||
Reworked by Markus Sattler, December 2015
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef ESP32WIFISTA_H_
|
||||
#define ESP32WIFISTA_H_
|
||||
|
||||
|
||||
#include "WiFiType.h"
|
||||
#include "WiFiGeneric.h"
|
||||
|
||||
|
||||
class WiFiSTAClass
|
||||
{
|
||||
// ----------------------------------------------------------------------------------------------
|
||||
// ---------------------------------------- STA function ----------------------------------------
|
||||
// ----------------------------------------------------------------------------------------------
|
||||
|
||||
public:
|
||||
|
||||
wl_status_t begin(const char* ssid, const char *passphrase = NULL, int32_t channel = 0, const uint8_t* bssid = NULL, bool connect = true);
|
||||
wl_status_t begin(char* ssid, char *passphrase = NULL, int32_t channel = 0, const uint8_t* bssid = NULL, bool connect = true);
|
||||
wl_status_t begin();
|
||||
|
||||
bool config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1 = (uint32_t)0x00000000, IPAddress dns2 = (uint32_t)0x00000000);
|
||||
|
||||
bool reconnect();
|
||||
bool disconnect(bool wifioff = false);
|
||||
|
||||
bool isConnected();
|
||||
|
||||
bool setAutoConnect(bool autoConnect);
|
||||
bool getAutoConnect();
|
||||
|
||||
bool setAutoReconnect(bool autoReconnect);
|
||||
bool getAutoReconnect();
|
||||
|
||||
uint8_t waitForConnectResult();
|
||||
|
||||
// STA network info
|
||||
IPAddress localIP();
|
||||
|
||||
uint8_t * macAddress(uint8_t* mac);
|
||||
String macAddress();
|
||||
|
||||
IPAddress subnetMask();
|
||||
IPAddress gatewayIP();
|
||||
IPAddress dnsIP(uint8_t dns_no = 0);
|
||||
|
||||
bool enableIpV6();
|
||||
IPv6Address localIPv6();
|
||||
|
||||
const char * getHostname();
|
||||
bool setHostname(const char * hostname);
|
||||
|
||||
// STA WiFi info
|
||||
static wl_status_t status();
|
||||
String SSID() const;
|
||||
String psk() const;
|
||||
|
||||
uint8_t * BSSID();
|
||||
String BSSIDstr();
|
||||
|
||||
int8_t RSSI();
|
||||
|
||||
static void _setStatus(wl_status_t status);
|
||||
protected:
|
||||
static wl_status_t _status;
|
||||
static bool _useStaticIp;
|
||||
static bool _autoReconnect;
|
||||
|
||||
public:
|
||||
bool beginSmartConfig();
|
||||
bool stopSmartConfig();
|
||||
bool smartConfigDone();
|
||||
|
||||
protected:
|
||||
static bool _smartConfigStarted;
|
||||
static bool _smartConfigDone;
|
||||
static void _smartConfigCallback(uint32_t status, void* result);
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif /* ESP32WIFISTA_H_ */
|
||||
|
@ -1,276 +1,276 @@
|
||||
/*
|
||||
ESP8266WiFiScan.cpp - WiFi library for esp8266
|
||||
|
||||
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
|
||||
This file is part of the esp8266 core for Arduino environment.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Reworked on 28 Dec 2015 by Markus Sattler
|
||||
|
||||
*/
|
||||
|
||||
#include "WiFi.h"
|
||||
#include "WiFiGeneric.h"
|
||||
#include "WiFiScan.h"
|
||||
|
||||
extern "C" {
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include <esp_err.h>
|
||||
#include <esp_wifi.h>
|
||||
#include <esp_event_loop.h>
|
||||
#include <esp32-hal.h>
|
||||
#include <lwip/ip_addr.h>
|
||||
#include "lwip/err.h"
|
||||
}
|
||||
|
||||
bool WiFiScanClass::_scanAsync = false;
|
||||
bool WiFiScanClass::_scanStarted = false;
|
||||
bool WiFiScanClass::_scanComplete = false;
|
||||
|
||||
uint16_t WiFiScanClass::_scanCount = 0;
|
||||
void* WiFiScanClass::_scanResult = 0;
|
||||
|
||||
/**
|
||||
* Start scan WiFi networks available
|
||||
* @param async run in async mode
|
||||
* @param show_hidden show hidden networks
|
||||
* @return Number of discovered networks
|
||||
*/
|
||||
int8_t WiFiScanClass::scanNetworks(bool async, bool show_hidden, bool passive, uint32_t max_ms_per_chan)
|
||||
{
|
||||
if(WiFiScanClass::_scanStarted) {
|
||||
return WIFI_SCAN_RUNNING;
|
||||
}
|
||||
|
||||
WiFiScanClass::_scanAsync = async;
|
||||
|
||||
WiFi.enableSTA(true);
|
||||
|
||||
scanDelete();
|
||||
|
||||
wifi_scan_config_t config;
|
||||
config.ssid = 0;
|
||||
config.bssid = 0;
|
||||
config.channel = 0;
|
||||
config.show_hidden = show_hidden;
|
||||
if(passive){
|
||||
config.scan_type = WIFI_SCAN_TYPE_PASSIVE;
|
||||
config.scan_time.passive = max_ms_per_chan;
|
||||
} else {
|
||||
config.scan_type = WIFI_SCAN_TYPE_ACTIVE;
|
||||
config.scan_time.active.min = 100;
|
||||
config.scan_time.active.max = max_ms_per_chan;
|
||||
}
|
||||
if(esp_wifi_scan_start(&config, false) == ESP_OK) {
|
||||
WiFiScanClass::_scanComplete = false;
|
||||
WiFiScanClass::_scanStarted = true;
|
||||
|
||||
if(WiFiScanClass::_scanAsync) {
|
||||
return WIFI_SCAN_RUNNING;
|
||||
}
|
||||
while(!(WiFiScanClass::_scanComplete)) {
|
||||
delay(10);
|
||||
}
|
||||
return WiFiScanClass::_scanCount;
|
||||
} else {
|
||||
return WIFI_SCAN_FAILED;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* private
|
||||
* scan callback
|
||||
* @param result void *arg
|
||||
* @param status STATUS
|
||||
*/
|
||||
void WiFiScanClass::_scanDone()
|
||||
{
|
||||
WiFiScanClass::_scanComplete = true;
|
||||
WiFiScanClass::_scanStarted = false;
|
||||
esp_wifi_scan_get_ap_num(&(WiFiScanClass::_scanCount));
|
||||
if(WiFiScanClass::_scanCount) {
|
||||
WiFiScanClass::_scanResult = new wifi_ap_record_t[WiFiScanClass::_scanCount];
|
||||
if(WiFiScanClass::_scanResult) {
|
||||
esp_wifi_scan_get_ap_records(&(WiFiScanClass::_scanCount), (wifi_ap_record_t*)_scanResult);
|
||||
} else {
|
||||
//no memory
|
||||
WiFiScanClass::_scanCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param i specify from which network item want to get the information
|
||||
* @return bss_info *
|
||||
*/
|
||||
void * WiFiScanClass::_getScanInfoByIndex(int i)
|
||||
{
|
||||
if(!WiFiScanClass::_scanResult || (size_t) i > WiFiScanClass::_scanCount) {
|
||||
return 0;
|
||||
}
|
||||
return reinterpret_cast<wifi_ap_record_t*>(WiFiScanClass::_scanResult) + i;
|
||||
}
|
||||
|
||||
/**
|
||||
* called to get the scan state in Async mode
|
||||
* @return scan result or status
|
||||
* -1 if scan not fin
|
||||
* -2 if scan not triggered
|
||||
*/
|
||||
int8_t WiFiScanClass::scanComplete()
|
||||
{
|
||||
|
||||
if(_scanStarted) {
|
||||
return WIFI_SCAN_RUNNING;
|
||||
}
|
||||
|
||||
if(_scanComplete) {
|
||||
return WiFiScanClass::_scanCount;
|
||||
}
|
||||
|
||||
return WIFI_SCAN_FAILED;
|
||||
}
|
||||
|
||||
/**
|
||||
* delete last scan result from RAM
|
||||
*/
|
||||
void WiFiScanClass::scanDelete()
|
||||
{
|
||||
if(WiFiScanClass::_scanResult) {
|
||||
delete[] reinterpret_cast<wifi_ap_record_t*>(WiFiScanClass::_scanResult);
|
||||
WiFiScanClass::_scanResult = 0;
|
||||
WiFiScanClass::_scanCount = 0;
|
||||
}
|
||||
_scanComplete = false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* loads all infos from a scanned wifi in to the ptr parameters
|
||||
* @param networkItem uint8_t
|
||||
* @param ssid const char**
|
||||
* @param encryptionType uint8_t *
|
||||
* @param RSSI int32_t *
|
||||
* @param BSSID uint8_t **
|
||||
* @param channel int32_t *
|
||||
* @return (true if ok)
|
||||
*/
|
||||
bool WiFiScanClass::getNetworkInfo(uint8_t i, String &ssid, uint8_t &encType, int32_t &rssi, uint8_t* &bssid, int32_t &channel)
|
||||
{
|
||||
wifi_ap_record_t* it = reinterpret_cast<wifi_ap_record_t*>(_getScanInfoByIndex(i));
|
||||
if(!it) {
|
||||
return false;
|
||||
}
|
||||
ssid = (const char*) it->ssid;
|
||||
encType = it->authmode;
|
||||
rssi = it->rssi;
|
||||
bssid = it->bssid;
|
||||
channel = it->primary;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the SSID discovered during the network scan.
|
||||
* @param i specify from which network item want to get the information
|
||||
* @return ssid string of the specified item on the networks scanned list
|
||||
*/
|
||||
String WiFiScanClass::SSID(uint8_t i)
|
||||
{
|
||||
wifi_ap_record_t* it = reinterpret_cast<wifi_ap_record_t*>(_getScanInfoByIndex(i));
|
||||
if(!it) {
|
||||
return String();
|
||||
}
|
||||
return String(reinterpret_cast<const char*>(it->ssid));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the encryption type of the networks discovered during the scanNetworks
|
||||
* @param i specify from which network item want to get the information
|
||||
* @return encryption type (enum wl_enc_type) of the specified item on the networks scanned list
|
||||
*/
|
||||
wifi_auth_mode_t WiFiScanClass::encryptionType(uint8_t i)
|
||||
{
|
||||
wifi_ap_record_t* it = reinterpret_cast<wifi_ap_record_t*>(_getScanInfoByIndex(i));
|
||||
if(!it) {
|
||||
return WIFI_AUTH_OPEN;
|
||||
}
|
||||
return it->authmode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the RSSI of the networks discovered during the scanNetworks
|
||||
* @param i specify from which network item want to get the information
|
||||
* @return signed value of RSSI of the specified item on the networks scanned list
|
||||
*/
|
||||
int32_t WiFiScanClass::RSSI(uint8_t i)
|
||||
{
|
||||
wifi_ap_record_t* it = reinterpret_cast<wifi_ap_record_t*>(_getScanInfoByIndex(i));
|
||||
if(!it) {
|
||||
return 0;
|
||||
}
|
||||
return it->rssi;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* return MAC / BSSID of scanned wifi
|
||||
* @param i specify from which network item want to get the information
|
||||
* @return uint8_t * MAC / BSSID of scanned wifi
|
||||
*/
|
||||
uint8_t * WiFiScanClass::BSSID(uint8_t i)
|
||||
{
|
||||
wifi_ap_record_t* it = reinterpret_cast<wifi_ap_record_t*>(_getScanInfoByIndex(i));
|
||||
if(!it) {
|
||||
return 0;
|
||||
}
|
||||
return it->bssid;
|
||||
}
|
||||
|
||||
/**
|
||||
* return MAC / BSSID of scanned wifi
|
||||
* @param i specify from which network item want to get the information
|
||||
* @return String MAC / BSSID of scanned wifi
|
||||
*/
|
||||
String WiFiScanClass::BSSIDstr(uint8_t i)
|
||||
{
|
||||
char mac[18] = { 0 };
|
||||
wifi_ap_record_t* it = reinterpret_cast<wifi_ap_record_t*>(_getScanInfoByIndex(i));
|
||||
if(!it) {
|
||||
return String();
|
||||
}
|
||||
sprintf(mac, "%02X:%02X:%02X:%02X:%02X:%02X", it->bssid[0], it->bssid[1], it->bssid[2], it->bssid[3], it->bssid[4], it->bssid[5]);
|
||||
return String(mac);
|
||||
}
|
||||
|
||||
int32_t WiFiScanClass::channel(uint8_t i)
|
||||
{
|
||||
wifi_ap_record_t* it = reinterpret_cast<wifi_ap_record_t*>(_getScanInfoByIndex(i));
|
||||
if(!it) {
|
||||
return 0;
|
||||
}
|
||||
return it->primary;
|
||||
}
|
||||
|
||||
/*
|
||||
ESP8266WiFiScan.cpp - WiFi library for esp8266
|
||||
|
||||
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
|
||||
This file is part of the esp8266 core for Arduino environment.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Reworked on 28 Dec 2015 by Markus Sattler
|
||||
|
||||
*/
|
||||
|
||||
#include "WiFi.h"
|
||||
#include "WiFiGeneric.h"
|
||||
#include "WiFiScan.h"
|
||||
|
||||
extern "C" {
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include <esp_err.h>
|
||||
#include <esp_wifi.h>
|
||||
#include <esp_event_loop.h>
|
||||
#include <esp32-hal.h>
|
||||
#include <lwip/ip_addr.h>
|
||||
#include "lwip/err.h"
|
||||
}
|
||||
|
||||
bool WiFiScanClass::_scanAsync = false;
|
||||
bool WiFiScanClass::_scanStarted = false;
|
||||
bool WiFiScanClass::_scanComplete = false;
|
||||
|
||||
uint16_t WiFiScanClass::_scanCount = 0;
|
||||
void* WiFiScanClass::_scanResult = 0;
|
||||
|
||||
/**
|
||||
* Start scan WiFi networks available
|
||||
* @param async run in async mode
|
||||
* @param show_hidden show hidden networks
|
||||
* @return Number of discovered networks
|
||||
*/
|
||||
int8_t WiFiScanClass::scanNetworks(bool async, bool show_hidden, bool passive, uint32_t max_ms_per_chan)
|
||||
{
|
||||
if(WiFiScanClass::_scanStarted) {
|
||||
return WIFI_SCAN_RUNNING;
|
||||
}
|
||||
|
||||
WiFiScanClass::_scanAsync = async;
|
||||
|
||||
WiFi.enableSTA(true);
|
||||
|
||||
scanDelete();
|
||||
|
||||
wifi_scan_config_t config;
|
||||
config.ssid = 0;
|
||||
config.bssid = 0;
|
||||
config.channel = 0;
|
||||
config.show_hidden = show_hidden;
|
||||
if(passive){
|
||||
config.scan_type = WIFI_SCAN_TYPE_PASSIVE;
|
||||
config.scan_time.passive = max_ms_per_chan;
|
||||
} else {
|
||||
config.scan_type = WIFI_SCAN_TYPE_ACTIVE;
|
||||
config.scan_time.active.min = 100;
|
||||
config.scan_time.active.max = max_ms_per_chan;
|
||||
}
|
||||
if(esp_wifi_scan_start(&config, false) == ESP_OK) {
|
||||
WiFiScanClass::_scanComplete = false;
|
||||
WiFiScanClass::_scanStarted = true;
|
||||
|
||||
if(WiFiScanClass::_scanAsync) {
|
||||
return WIFI_SCAN_RUNNING;
|
||||
}
|
||||
while(!(WiFiScanClass::_scanComplete)) {
|
||||
delay(10);
|
||||
}
|
||||
return WiFiScanClass::_scanCount;
|
||||
} else {
|
||||
return WIFI_SCAN_FAILED;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* private
|
||||
* scan callback
|
||||
* @param result void *arg
|
||||
* @param status STATUS
|
||||
*/
|
||||
void WiFiScanClass::_scanDone()
|
||||
{
|
||||
WiFiScanClass::_scanComplete = true;
|
||||
WiFiScanClass::_scanStarted = false;
|
||||
esp_wifi_scan_get_ap_num(&(WiFiScanClass::_scanCount));
|
||||
if(WiFiScanClass::_scanCount) {
|
||||
WiFiScanClass::_scanResult = new wifi_ap_record_t[WiFiScanClass::_scanCount];
|
||||
if(WiFiScanClass::_scanResult) {
|
||||
esp_wifi_scan_get_ap_records(&(WiFiScanClass::_scanCount), (wifi_ap_record_t*)_scanResult);
|
||||
} else {
|
||||
//no memory
|
||||
WiFiScanClass::_scanCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param i specify from which network item want to get the information
|
||||
* @return bss_info *
|
||||
*/
|
||||
void * WiFiScanClass::_getScanInfoByIndex(int i)
|
||||
{
|
||||
if(!WiFiScanClass::_scanResult || (size_t) i > WiFiScanClass::_scanCount) {
|
||||
return 0;
|
||||
}
|
||||
return reinterpret_cast<wifi_ap_record_t*>(WiFiScanClass::_scanResult) + i;
|
||||
}
|
||||
|
||||
/**
|
||||
* called to get the scan state in Async mode
|
||||
* @return scan result or status
|
||||
* -1 if scan not fin
|
||||
* -2 if scan not triggered
|
||||
*/
|
||||
int8_t WiFiScanClass::scanComplete()
|
||||
{
|
||||
|
||||
if(_scanStarted) {
|
||||
return WIFI_SCAN_RUNNING;
|
||||
}
|
||||
|
||||
if(_scanComplete) {
|
||||
return WiFiScanClass::_scanCount;
|
||||
}
|
||||
|
||||
return WIFI_SCAN_FAILED;
|
||||
}
|
||||
|
||||
/**
|
||||
* delete last scan result from RAM
|
||||
*/
|
||||
void WiFiScanClass::scanDelete()
|
||||
{
|
||||
if(WiFiScanClass::_scanResult) {
|
||||
delete[] reinterpret_cast<wifi_ap_record_t*>(WiFiScanClass::_scanResult);
|
||||
WiFiScanClass::_scanResult = 0;
|
||||
WiFiScanClass::_scanCount = 0;
|
||||
}
|
||||
_scanComplete = false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* loads all infos from a scanned wifi in to the ptr parameters
|
||||
* @param networkItem uint8_t
|
||||
* @param ssid const char**
|
||||
* @param encryptionType uint8_t *
|
||||
* @param RSSI int32_t *
|
||||
* @param BSSID uint8_t **
|
||||
* @param channel int32_t *
|
||||
* @return (true if ok)
|
||||
*/
|
||||
bool WiFiScanClass::getNetworkInfo(uint8_t i, String &ssid, uint8_t &encType, int32_t &rssi, uint8_t* &bssid, int32_t &channel)
|
||||
{
|
||||
wifi_ap_record_t* it = reinterpret_cast<wifi_ap_record_t*>(_getScanInfoByIndex(i));
|
||||
if(!it) {
|
||||
return false;
|
||||
}
|
||||
ssid = (const char*) it->ssid;
|
||||
encType = it->authmode;
|
||||
rssi = it->rssi;
|
||||
bssid = it->bssid;
|
||||
channel = it->primary;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the SSID discovered during the network scan.
|
||||
* @param i specify from which network item want to get the information
|
||||
* @return ssid string of the specified item on the networks scanned list
|
||||
*/
|
||||
String WiFiScanClass::SSID(uint8_t i)
|
||||
{
|
||||
wifi_ap_record_t* it = reinterpret_cast<wifi_ap_record_t*>(_getScanInfoByIndex(i));
|
||||
if(!it) {
|
||||
return String();
|
||||
}
|
||||
return String(reinterpret_cast<const char*>(it->ssid));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the encryption type of the networks discovered during the scanNetworks
|
||||
* @param i specify from which network item want to get the information
|
||||
* @return encryption type (enum wl_enc_type) of the specified item on the networks scanned list
|
||||
*/
|
||||
wifi_auth_mode_t WiFiScanClass::encryptionType(uint8_t i)
|
||||
{
|
||||
wifi_ap_record_t* it = reinterpret_cast<wifi_ap_record_t*>(_getScanInfoByIndex(i));
|
||||
if(!it) {
|
||||
return WIFI_AUTH_OPEN;
|
||||
}
|
||||
return it->authmode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the RSSI of the networks discovered during the scanNetworks
|
||||
* @param i specify from which network item want to get the information
|
||||
* @return signed value of RSSI of the specified item on the networks scanned list
|
||||
*/
|
||||
int32_t WiFiScanClass::RSSI(uint8_t i)
|
||||
{
|
||||
wifi_ap_record_t* it = reinterpret_cast<wifi_ap_record_t*>(_getScanInfoByIndex(i));
|
||||
if(!it) {
|
||||
return 0;
|
||||
}
|
||||
return it->rssi;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* return MAC / BSSID of scanned wifi
|
||||
* @param i specify from which network item want to get the information
|
||||
* @return uint8_t * MAC / BSSID of scanned wifi
|
||||
*/
|
||||
uint8_t * WiFiScanClass::BSSID(uint8_t i)
|
||||
{
|
||||
wifi_ap_record_t* it = reinterpret_cast<wifi_ap_record_t*>(_getScanInfoByIndex(i));
|
||||
if(!it) {
|
||||
return 0;
|
||||
}
|
||||
return it->bssid;
|
||||
}
|
||||
|
||||
/**
|
||||
* return MAC / BSSID of scanned wifi
|
||||
* @param i specify from which network item want to get the information
|
||||
* @return String MAC / BSSID of scanned wifi
|
||||
*/
|
||||
String WiFiScanClass::BSSIDstr(uint8_t i)
|
||||
{
|
||||
char mac[18] = { 0 };
|
||||
wifi_ap_record_t* it = reinterpret_cast<wifi_ap_record_t*>(_getScanInfoByIndex(i));
|
||||
if(!it) {
|
||||
return String();
|
||||
}
|
||||
sprintf(mac, "%02X:%02X:%02X:%02X:%02X:%02X", it->bssid[0], it->bssid[1], it->bssid[2], it->bssid[3], it->bssid[4], it->bssid[5]);
|
||||
return String(mac);
|
||||
}
|
||||
|
||||
int32_t WiFiScanClass::channel(uint8_t i)
|
||||
{
|
||||
wifi_ap_record_t* it = reinterpret_cast<wifi_ap_record_t*>(_getScanInfoByIndex(i));
|
||||
if(!it) {
|
||||
return 0;
|
||||
}
|
||||
return it->primary;
|
||||
}
|
||||
|
||||
|
@ -1,64 +1,64 @@
|
||||
/*
|
||||
ESP8266WiFiScan.h - esp8266 Wifi support.
|
||||
Based on WiFi.h from Ardiono WiFi shield library.
|
||||
Copyright (c) 2011-2014 Arduino. All right reserved.
|
||||
Modified by Ivan Grokhotkov, December 2014
|
||||
Reworked by Markus Sattler, December 2015
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef ESP32WIFISCAN_H_
|
||||
#define ESP32WIFISCAN_H_
|
||||
|
||||
#include "WiFiType.h"
|
||||
#include "WiFiGeneric.h"
|
||||
|
||||
class WiFiScanClass
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
int8_t scanNetworks(bool async = false, bool show_hidden = false, bool passive = false, uint32_t max_ms_per_chan = 300);
|
||||
|
||||
int8_t scanComplete();
|
||||
void scanDelete();
|
||||
|
||||
// scan result
|
||||
bool getNetworkInfo(uint8_t networkItem, String &ssid, uint8_t &encryptionType, int32_t &RSSI, uint8_t* &BSSID, int32_t &channel);
|
||||
|
||||
String SSID(uint8_t networkItem);
|
||||
wifi_auth_mode_t encryptionType(uint8_t networkItem);
|
||||
int32_t RSSI(uint8_t networkItem);
|
||||
uint8_t * BSSID(uint8_t networkItem);
|
||||
String BSSIDstr(uint8_t networkItem);
|
||||
int32_t channel(uint8_t networkItem);
|
||||
|
||||
static void _scanDone();
|
||||
protected:
|
||||
|
||||
static bool _scanAsync;
|
||||
static bool _scanStarted;
|
||||
static bool _scanComplete;
|
||||
|
||||
static uint16_t _scanCount;
|
||||
static void* _scanResult;
|
||||
|
||||
static void * _getScanInfoByIndex(int i);
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif /* ESP32WIFISCAN_H_ */
|
||||
/*
|
||||
ESP8266WiFiScan.h - esp8266 Wifi support.
|
||||
Based on WiFi.h from Ardiono WiFi shield library.
|
||||
Copyright (c) 2011-2014 Arduino. All right reserved.
|
||||
Modified by Ivan Grokhotkov, December 2014
|
||||
Reworked by Markus Sattler, December 2015
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef ESP32WIFISCAN_H_
|
||||
#define ESP32WIFISCAN_H_
|
||||
|
||||
#include "WiFiType.h"
|
||||
#include "WiFiGeneric.h"
|
||||
|
||||
class WiFiScanClass
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
int8_t scanNetworks(bool async = false, bool show_hidden = false, bool passive = false, uint32_t max_ms_per_chan = 300);
|
||||
|
||||
int8_t scanComplete();
|
||||
void scanDelete();
|
||||
|
||||
// scan result
|
||||
bool getNetworkInfo(uint8_t networkItem, String &ssid, uint8_t &encryptionType, int32_t &RSSI, uint8_t* &BSSID, int32_t &channel);
|
||||
|
||||
String SSID(uint8_t networkItem);
|
||||
wifi_auth_mode_t encryptionType(uint8_t networkItem);
|
||||
int32_t RSSI(uint8_t networkItem);
|
||||
uint8_t * BSSID(uint8_t networkItem);
|
||||
String BSSIDstr(uint8_t networkItem);
|
||||
int32_t channel(uint8_t networkItem);
|
||||
|
||||
static void _scanDone();
|
||||
protected:
|
||||
|
||||
static bool _scanAsync;
|
||||
static bool _scanStarted;
|
||||
static bool _scanComplete;
|
||||
|
||||
static uint16_t _scanCount;
|
||||
static void* _scanResult;
|
||||
|
||||
static void * _getScanInfoByIndex(int i);
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif /* ESP32WIFISCAN_H_ */
|
||||
|
@ -1,48 +1,48 @@
|
||||
/*
|
||||
ESP8266WiFiType.h - esp8266 Wifi support.
|
||||
Copyright (c) 2011-2014 Arduino. All right reserved.
|
||||
Modified by Ivan Grokhotkov, December 2014
|
||||
Reworked by Markus Sattler, December 2015
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
|
||||
#ifndef ESP32WIFITYPE_H_
|
||||
#define ESP32WIFITYPE_H_
|
||||
|
||||
#define WIFI_SCAN_RUNNING (-1)
|
||||
#define WIFI_SCAN_FAILED (-2)
|
||||
|
||||
#define WiFiMode_t wifi_mode_t
|
||||
#define WIFI_OFF WIFI_MODE_NULL
|
||||
#define WIFI_STA WIFI_MODE_STA
|
||||
#define WIFI_AP WIFI_MODE_AP
|
||||
#define WIFI_AP_STA WIFI_MODE_APSTA
|
||||
|
||||
#define WiFiEvent_t system_event_id_t
|
||||
|
||||
typedef enum {
|
||||
WL_NO_SHIELD = 255, // for compatibility with WiFi Shield library
|
||||
WL_IDLE_STATUS = 0,
|
||||
WL_NO_SSID_AVAIL = 1,
|
||||
WL_SCAN_COMPLETED = 2,
|
||||
WL_CONNECTED = 3,
|
||||
WL_CONNECT_FAILED = 4,
|
||||
WL_CONNECTION_LOST = 5,
|
||||
WL_DISCONNECTED = 6
|
||||
} wl_status_t;
|
||||
|
||||
#endif /* ESP32WIFITYPE_H_ */
|
||||
/*
|
||||
ESP8266WiFiType.h - esp8266 Wifi support.
|
||||
Copyright (c) 2011-2014 Arduino. All right reserved.
|
||||
Modified by Ivan Grokhotkov, December 2014
|
||||
Reworked by Markus Sattler, December 2015
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
|
||||
#ifndef ESP32WIFITYPE_H_
|
||||
#define ESP32WIFITYPE_H_
|
||||
|
||||
#define WIFI_SCAN_RUNNING (-1)
|
||||
#define WIFI_SCAN_FAILED (-2)
|
||||
|
||||
#define WiFiMode_t wifi_mode_t
|
||||
#define WIFI_OFF WIFI_MODE_NULL
|
||||
#define WIFI_STA WIFI_MODE_STA
|
||||
#define WIFI_AP WIFI_MODE_AP
|
||||
#define WIFI_AP_STA WIFI_MODE_APSTA
|
||||
|
||||
#define WiFiEvent_t system_event_id_t
|
||||
|
||||
typedef enum {
|
||||
WL_NO_SHIELD = 255, // for compatibility with WiFi Shield library
|
||||
WL_IDLE_STATUS = 0,
|
||||
WL_NO_SSID_AVAIL = 1,
|
||||
WL_SCAN_COMPLETED = 2,
|
||||
WL_CONNECTED = 3,
|
||||
WL_CONNECT_FAILED = 4,
|
||||
WL_CONNECTION_LOST = 5,
|
||||
WL_DISCONNECTED = 6
|
||||
} wl_status_t;
|
||||
|
||||
#endif /* ESP32WIFITYPE_H_ */
|
||||
|
@ -107,4 +107,4 @@ void setup() {
|
||||
|
||||
void loop() {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
@ -1,222 +1,222 @@
|
||||
/*
|
||||
WiFiClientSecure.cpp - Client Secure class for ESP32
|
||||
Copyright (c) 2016 Hristo Gochkov All right reserved.
|
||||
Additions Copyright (C) 2017 Evandro Luis Copercini.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "WiFiClientSecure.h"
|
||||
#include <lwip/sockets.h>
|
||||
#include <lwip/netdb.h>
|
||||
#include <errno.h>
|
||||
|
||||
#undef connect
|
||||
#undef write
|
||||
#undef read
|
||||
|
||||
|
||||
WiFiClientSecure::WiFiClientSecure()
|
||||
{
|
||||
_connected = false;
|
||||
|
||||
sslclient = new sslclient_context;
|
||||
ssl_init(sslclient);
|
||||
sslclient->socket = -1;
|
||||
|
||||
_CA_cert = NULL;
|
||||
_cert = NULL;
|
||||
_private_key = NULL;
|
||||
next = NULL;
|
||||
}
|
||||
|
||||
|
||||
WiFiClientSecure::WiFiClientSecure(int sock)
|
||||
{
|
||||
_connected = false;
|
||||
|
||||
sslclient = new sslclient_context;
|
||||
ssl_init(sslclient);
|
||||
sslclient->socket = sock;
|
||||
|
||||
if (sock >= 0) {
|
||||
_connected = true;
|
||||
}
|
||||
|
||||
_CA_cert = NULL;
|
||||
_cert = NULL;
|
||||
_private_key = NULL;
|
||||
next = NULL;
|
||||
}
|
||||
|
||||
WiFiClientSecure::~WiFiClientSecure()
|
||||
{
|
||||
stop();
|
||||
delete sslclient;
|
||||
}
|
||||
|
||||
WiFiClientSecure &WiFiClientSecure::operator=(const WiFiClientSecure &other)
|
||||
{
|
||||
stop();
|
||||
sslclient->socket = other.sslclient->socket;
|
||||
_connected = other._connected;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void WiFiClientSecure::stop()
|
||||
{
|
||||
if (sslclient->socket >= 0) {
|
||||
close(sslclient->socket);
|
||||
sslclient->socket = -1;
|
||||
_connected = false;
|
||||
}
|
||||
stop_ssl_socket(sslclient, _CA_cert, _cert, _private_key);
|
||||
}
|
||||
|
||||
int WiFiClientSecure::connect(IPAddress ip, uint16_t port)
|
||||
{
|
||||
return connect(ip, port, _CA_cert, _cert, _private_key);
|
||||
}
|
||||
|
||||
int WiFiClientSecure::connect(const char *host, uint16_t port)
|
||||
{
|
||||
return connect(host, port, _CA_cert, _cert, _private_key);
|
||||
}
|
||||
|
||||
int WiFiClientSecure::connect(IPAddress ip, uint16_t port, const char *_CA_cert, const char *_cert, const char *_private_key)
|
||||
{
|
||||
return connect(ip.toString().c_str(), port, _CA_cert, _cert, _private_key);
|
||||
}
|
||||
|
||||
int WiFiClientSecure::connect(const char *host, uint16_t port, const char *_CA_cert, const char *_cert, const char *_private_key)
|
||||
{
|
||||
int ret = start_ssl_client(sslclient, host, port, _CA_cert, _cert, _private_key);
|
||||
_lastError = ret;
|
||||
if (ret < 0) {
|
||||
log_e("lwip_connect_r: %d", errno);
|
||||
stop();
|
||||
return 0;
|
||||
}
|
||||
_connected = true;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int WiFiClientSecure::peek(){
|
||||
if(_peek >= 0){
|
||||
return _peek;
|
||||
}
|
||||
_peek = read();
|
||||
return _peek;
|
||||
}
|
||||
|
||||
size_t WiFiClientSecure::write(uint8_t data)
|
||||
{
|
||||
return write(&data, 1);
|
||||
}
|
||||
|
||||
int WiFiClientSecure::read()
|
||||
{
|
||||
uint8_t data = -1;
|
||||
|
||||
if(_peek >= 0){
|
||||
data = _peek;
|
||||
_peek = -1;
|
||||
return data;
|
||||
}
|
||||
|
||||
int res = read(&data, 1);
|
||||
if (res < 0) {
|
||||
return res;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
size_t WiFiClientSecure::write(const uint8_t *buf, size_t size)
|
||||
{
|
||||
if (!_connected) {
|
||||
return 0;
|
||||
}
|
||||
int res = send_ssl_data(sslclient, buf, size);
|
||||
if (res < 0) {
|
||||
stop();
|
||||
res = 0;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int WiFiClientSecure::read(uint8_t *buf, size_t size)
|
||||
{
|
||||
if(_peek >= 0){
|
||||
uint8_t data = -1;
|
||||
data = _peek;
|
||||
_peek = -1;
|
||||
return data;
|
||||
}
|
||||
|
||||
if (!available()) {
|
||||
return -1;
|
||||
}
|
||||
int res = get_ssl_receive(sslclient, buf, size);
|
||||
if (res < 0) {
|
||||
stop();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int WiFiClientSecure::available()
|
||||
{
|
||||
if (!_connected) {
|
||||
return 0;
|
||||
}
|
||||
int res = data_to_read(sslclient);
|
||||
if (res < 0 ) {
|
||||
stop();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
uint8_t WiFiClientSecure::connected()
|
||||
{
|
||||
uint8_t dummy = 0;
|
||||
read(&dummy, 0);
|
||||
|
||||
return _connected;
|
||||
}
|
||||
|
||||
void WiFiClientSecure::setCACert (const char *rootCA)
|
||||
{
|
||||
_CA_cert = rootCA;
|
||||
}
|
||||
|
||||
void WiFiClientSecure::setCertificate (const char *client_ca)
|
||||
{
|
||||
_cert = client_ca;
|
||||
}
|
||||
|
||||
void WiFiClientSecure::setPrivateKey (const char *private_key)
|
||||
{
|
||||
_private_key = private_key;
|
||||
}
|
||||
|
||||
int WiFiClientSecure::lastError(char *buf, const size_t size)
|
||||
{
|
||||
if (!_lastError) {
|
||||
return 0;
|
||||
}
|
||||
char error_buf[100];
|
||||
mbedtls_strerror(_lastError, error_buf, 100);
|
||||
snprintf(buf, size, "%s", error_buf);
|
||||
return _lastError;
|
||||
}
|
||||
/*
|
||||
WiFiClientSecure.cpp - Client Secure class for ESP32
|
||||
Copyright (c) 2016 Hristo Gochkov All right reserved.
|
||||
Additions Copyright (C) 2017 Evandro Luis Copercini.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "WiFiClientSecure.h"
|
||||
#include <lwip/sockets.h>
|
||||
#include <lwip/netdb.h>
|
||||
#include <errno.h>
|
||||
|
||||
#undef connect
|
||||
#undef write
|
||||
#undef read
|
||||
|
||||
|
||||
WiFiClientSecure::WiFiClientSecure()
|
||||
{
|
||||
_connected = false;
|
||||
|
||||
sslclient = new sslclient_context;
|
||||
ssl_init(sslclient);
|
||||
sslclient->socket = -1;
|
||||
|
||||
_CA_cert = NULL;
|
||||
_cert = NULL;
|
||||
_private_key = NULL;
|
||||
next = NULL;
|
||||
}
|
||||
|
||||
|
||||
WiFiClientSecure::WiFiClientSecure(int sock)
|
||||
{
|
||||
_connected = false;
|
||||
|
||||
sslclient = new sslclient_context;
|
||||
ssl_init(sslclient);
|
||||
sslclient->socket = sock;
|
||||
|
||||
if (sock >= 0) {
|
||||
_connected = true;
|
||||
}
|
||||
|
||||
_CA_cert = NULL;
|
||||
_cert = NULL;
|
||||
_private_key = NULL;
|
||||
next = NULL;
|
||||
}
|
||||
|
||||
WiFiClientSecure::~WiFiClientSecure()
|
||||
{
|
||||
stop();
|
||||
delete sslclient;
|
||||
}
|
||||
|
||||
WiFiClientSecure &WiFiClientSecure::operator=(const WiFiClientSecure &other)
|
||||
{
|
||||
stop();
|
||||
sslclient->socket = other.sslclient->socket;
|
||||
_connected = other._connected;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void WiFiClientSecure::stop()
|
||||
{
|
||||
if (sslclient->socket >= 0) {
|
||||
close(sslclient->socket);
|
||||
sslclient->socket = -1;
|
||||
_connected = false;
|
||||
}
|
||||
stop_ssl_socket(sslclient, _CA_cert, _cert, _private_key);
|
||||
}
|
||||
|
||||
int WiFiClientSecure::connect(IPAddress ip, uint16_t port)
|
||||
{
|
||||
return connect(ip, port, _CA_cert, _cert, _private_key);
|
||||
}
|
||||
|
||||
int WiFiClientSecure::connect(const char *host, uint16_t port)
|
||||
{
|
||||
return connect(host, port, _CA_cert, _cert, _private_key);
|
||||
}
|
||||
|
||||
int WiFiClientSecure::connect(IPAddress ip, uint16_t port, const char *_CA_cert, const char *_cert, const char *_private_key)
|
||||
{
|
||||
return connect(ip.toString().c_str(), port, _CA_cert, _cert, _private_key);
|
||||
}
|
||||
|
||||
int WiFiClientSecure::connect(const char *host, uint16_t port, const char *_CA_cert, const char *_cert, const char *_private_key)
|
||||
{
|
||||
int ret = start_ssl_client(sslclient, host, port, _CA_cert, _cert, _private_key);
|
||||
_lastError = ret;
|
||||
if (ret < 0) {
|
||||
log_e("lwip_connect_r: %d", errno);
|
||||
stop();
|
||||
return 0;
|
||||
}
|
||||
_connected = true;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int WiFiClientSecure::peek(){
|
||||
if(_peek >= 0){
|
||||
return _peek;
|
||||
}
|
||||
_peek = read();
|
||||
return _peek;
|
||||
}
|
||||
|
||||
size_t WiFiClientSecure::write(uint8_t data)
|
||||
{
|
||||
return write(&data, 1);
|
||||
}
|
||||
|
||||
int WiFiClientSecure::read()
|
||||
{
|
||||
uint8_t data = -1;
|
||||
|
||||
if(_peek >= 0){
|
||||
data = _peek;
|
||||
_peek = -1;
|
||||
return data;
|
||||
}
|
||||
|
||||
int res = read(&data, 1);
|
||||
if (res < 0) {
|
||||
return res;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
size_t WiFiClientSecure::write(const uint8_t *buf, size_t size)
|
||||
{
|
||||
if (!_connected) {
|
||||
return 0;
|
||||
}
|
||||
int res = send_ssl_data(sslclient, buf, size);
|
||||
if (res < 0) {
|
||||
stop();
|
||||
res = 0;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int WiFiClientSecure::read(uint8_t *buf, size_t size)
|
||||
{
|
||||
if(_peek >= 0){
|
||||
uint8_t data = -1;
|
||||
data = _peek;
|
||||
_peek = -1;
|
||||
return data;
|
||||
}
|
||||
|
||||
if (!available()) {
|
||||
return -1;
|
||||
}
|
||||
int res = get_ssl_receive(sslclient, buf, size);
|
||||
if (res < 0) {
|
||||
stop();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int WiFiClientSecure::available()
|
||||
{
|
||||
if (!_connected) {
|
||||
return 0;
|
||||
}
|
||||
int res = data_to_read(sslclient);
|
||||
if (res < 0 ) {
|
||||
stop();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
uint8_t WiFiClientSecure::connected()
|
||||
{
|
||||
uint8_t dummy = 0;
|
||||
read(&dummy, 0);
|
||||
|
||||
return _connected;
|
||||
}
|
||||
|
||||
void WiFiClientSecure::setCACert (const char *rootCA)
|
||||
{
|
||||
_CA_cert = rootCA;
|
||||
}
|
||||
|
||||
void WiFiClientSecure::setCertificate (const char *client_ca)
|
||||
{
|
||||
_cert = client_ca;
|
||||
}
|
||||
|
||||
void WiFiClientSecure::setPrivateKey (const char *private_key)
|
||||
{
|
||||
_private_key = private_key;
|
||||
}
|
||||
|
||||
int WiFiClientSecure::lastError(char *buf, const size_t size)
|
||||
{
|
||||
if (!_lastError) {
|
||||
return 0;
|
||||
}
|
||||
char error_buf[100];
|
||||
mbedtls_strerror(_lastError, error_buf, 100);
|
||||
snprintf(buf, size, "%s", error_buf);
|
||||
return _lastError;
|
||||
}
|
||||
|
@ -1,90 +1,90 @@
|
||||
/*
|
||||
WiFiClientSecure.h - Base class that provides Client SSL to ESP32
|
||||
Copyright (c) 2011 Adrian McEwen. All right reserved.
|
||||
Additions Copyright (C) 2017 Evandro Luis Copercini.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef WiFiClientSecure_h
|
||||
#define WiFiClientSecure_h
|
||||
#include "Arduino.h"
|
||||
#include "IPAddress.h"
|
||||
#include <WiFi.h>
|
||||
#include "ssl_client.h"
|
||||
|
||||
class WiFiClientSecure : public WiFiClient
|
||||
{
|
||||
protected:
|
||||
sslclient_context *sslclient;
|
||||
|
||||
int _lastError = 0;
|
||||
int _peek = -1;
|
||||
const char *_CA_cert;
|
||||
const char *_cert;
|
||||
const char *_private_key;
|
||||
|
||||
public:
|
||||
WiFiClientSecure *next;
|
||||
WiFiClientSecure();
|
||||
WiFiClientSecure(int socket);
|
||||
~WiFiClientSecure();
|
||||
int connect(IPAddress ip, uint16_t port);
|
||||
int connect(const char *host, uint16_t port);
|
||||
int connect(IPAddress ip, uint16_t port, const char *rootCABuff, const char *cli_cert, const char *cli_key);
|
||||
int connect(const char *host, uint16_t port, const char *rootCABuff, const char *cli_cert, const char *cli_key);
|
||||
int peek();
|
||||
size_t write(uint8_t data);
|
||||
size_t write(const uint8_t *buf, size_t size);
|
||||
int available();
|
||||
int read();
|
||||
int read(uint8_t *buf, size_t size);
|
||||
void flush() {}
|
||||
void stop();
|
||||
uint8_t connected();
|
||||
int lastError(char *buf, const size_t size);
|
||||
void setCACert(const char *rootCA);
|
||||
void setCertificate(const char *client_ca);
|
||||
void setPrivateKey (const char *private_key);
|
||||
|
||||
operator bool()
|
||||
{
|
||||
return connected();
|
||||
}
|
||||
WiFiClientSecure &operator=(const WiFiClientSecure &other);
|
||||
bool operator==(const bool value)
|
||||
{
|
||||
return bool() == value;
|
||||
}
|
||||
bool operator!=(const bool value)
|
||||
{
|
||||
return bool() != value;
|
||||
}
|
||||
bool operator==(const WiFiClientSecure &);
|
||||
bool operator!=(const WiFiClientSecure &rhs)
|
||||
{
|
||||
return !this->operator==(rhs);
|
||||
};
|
||||
|
||||
int socket()
|
||||
{
|
||||
return sslclient->socket = -1;
|
||||
}
|
||||
|
||||
//friend class WiFiServer;
|
||||
using Print::write;
|
||||
};
|
||||
|
||||
#endif /* _WIFICLIENT_H_ */
|
||||
/*
|
||||
WiFiClientSecure.h - Base class that provides Client SSL to ESP32
|
||||
Copyright (c) 2011 Adrian McEwen. All right reserved.
|
||||
Additions Copyright (C) 2017 Evandro Luis Copercini.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef WiFiClientSecure_h
|
||||
#define WiFiClientSecure_h
|
||||
#include "Arduino.h"
|
||||
#include "IPAddress.h"
|
||||
#include <WiFi.h>
|
||||
#include "ssl_client.h"
|
||||
|
||||
class WiFiClientSecure : public WiFiClient
|
||||
{
|
||||
protected:
|
||||
sslclient_context *sslclient;
|
||||
|
||||
int _lastError = 0;
|
||||
int _peek = -1;
|
||||
const char *_CA_cert;
|
||||
const char *_cert;
|
||||
const char *_private_key;
|
||||
|
||||
public:
|
||||
WiFiClientSecure *next;
|
||||
WiFiClientSecure();
|
||||
WiFiClientSecure(int socket);
|
||||
~WiFiClientSecure();
|
||||
int connect(IPAddress ip, uint16_t port);
|
||||
int connect(const char *host, uint16_t port);
|
||||
int connect(IPAddress ip, uint16_t port, const char *rootCABuff, const char *cli_cert, const char *cli_key);
|
||||
int connect(const char *host, uint16_t port, const char *rootCABuff, const char *cli_cert, const char *cli_key);
|
||||
int peek();
|
||||
size_t write(uint8_t data);
|
||||
size_t write(const uint8_t *buf, size_t size);
|
||||
int available();
|
||||
int read();
|
||||
int read(uint8_t *buf, size_t size);
|
||||
void flush() {}
|
||||
void stop();
|
||||
uint8_t connected();
|
||||
int lastError(char *buf, const size_t size);
|
||||
void setCACert(const char *rootCA);
|
||||
void setCertificate(const char *client_ca);
|
||||
void setPrivateKey (const char *private_key);
|
||||
|
||||
operator bool()
|
||||
{
|
||||
return connected();
|
||||
}
|
||||
WiFiClientSecure &operator=(const WiFiClientSecure &other);
|
||||
bool operator==(const bool value)
|
||||
{
|
||||
return bool() == value;
|
||||
}
|
||||
bool operator!=(const bool value)
|
||||
{
|
||||
return bool() != value;
|
||||
}
|
||||
bool operator==(const WiFiClientSecure &);
|
||||
bool operator!=(const WiFiClientSecure &rhs)
|
||||
{
|
||||
return !this->operator==(rhs);
|
||||
};
|
||||
|
||||
int socket()
|
||||
{
|
||||
return sslclient->socket = -1;
|
||||
}
|
||||
|
||||
//friend class WiFiServer;
|
||||
using Print::write;
|
||||
};
|
||||
|
||||
#endif /* _WIFICLIENT_H_ */
|
||||
|
@ -1,264 +1,264 @@
|
||||
/* Provide SSL/TLS functions to ESP32 with Arduino IDE
|
||||
*
|
||||
* Adapted from the ssl_client1 example of mbedtls.
|
||||
*
|
||||
* Original Copyright (C) 2006-2015, ARM Limited, All Rights Reserved, Apache 2.0 License.
|
||||
* Additions Copyright (C) 2017 Evandro Luis Copercini, Apache 2.0 License.
|
||||
*/
|
||||
|
||||
#include "Arduino.h"
|
||||
#include <esp32-hal-log.h>
|
||||
#include <lwip/err.h>
|
||||
#include <lwip/sockets.h>
|
||||
#include <lwip/sys.h>
|
||||
#include <lwip/netdb.h>
|
||||
#include "ssl_client.h"
|
||||
|
||||
|
||||
const char *pers = "esp32-tls";
|
||||
|
||||
static int handle_error(int err)
|
||||
{
|
||||
if(err == -30848){
|
||||
return err;
|
||||
}
|
||||
#ifdef MBEDTLS_ERROR_C
|
||||
char error_buf[100];
|
||||
mbedtls_strerror(err, error_buf, 100);
|
||||
log_e("%s", error_buf);
|
||||
#endif
|
||||
log_e("MbedTLS message code: %d", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
void ssl_init(sslclient_context *ssl_client)
|
||||
{
|
||||
mbedtls_ssl_init(&ssl_client->ssl_ctx);
|
||||
mbedtls_ssl_config_init(&ssl_client->ssl_conf);
|
||||
mbedtls_ctr_drbg_init(&ssl_client->drbg_ctx);
|
||||
}
|
||||
|
||||
|
||||
int start_ssl_client(sslclient_context *ssl_client, const char *host, uint32_t port, const char *rootCABuff, const char *cli_cert, const char *cli_key)
|
||||
{
|
||||
char buf[512];
|
||||
int ret, flags, timeout;
|
||||
int enable = 1;
|
||||
log_v("Free heap before TLS %u", xPortGetFreeHeapSize());
|
||||
|
||||
log_v("Starting socket");
|
||||
ssl_client->socket = -1;
|
||||
|
||||
ssl_client->socket = lwip_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (ssl_client->socket < 0) {
|
||||
log_e("ERROR opening socket");
|
||||
return ssl_client->socket;
|
||||
}
|
||||
|
||||
struct hostent *server;
|
||||
server = gethostbyname(host);
|
||||
if (server == NULL) {
|
||||
log_e("gethostbyname failed");
|
||||
return -1;
|
||||
}
|
||||
IPAddress srv((const uint8_t *)(server->h_addr));
|
||||
|
||||
struct sockaddr_in serv_addr;
|
||||
memset(&serv_addr, 0, sizeof(serv_addr));
|
||||
serv_addr.sin_family = AF_INET;
|
||||
serv_addr.sin_addr.s_addr = srv;
|
||||
serv_addr.sin_port = htons(port);
|
||||
|
||||
if (lwip_connect(ssl_client->socket, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == 0) {
|
||||
timeout = 30000;
|
||||
lwip_setsockopt(ssl_client->socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
|
||||
lwip_setsockopt(ssl_client->socket, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
|
||||
lwip_setsockopt(ssl_client->socket, IPPROTO_TCP, TCP_NODELAY, &enable, sizeof(enable));
|
||||
lwip_setsockopt(ssl_client->socket, SOL_SOCKET, SO_KEEPALIVE, &enable, sizeof(enable));
|
||||
} else {
|
||||
log_e("Connect to Server failed!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fcntl( ssl_client->socket, F_SETFL, fcntl( ssl_client->socket, F_GETFL, 0 ) | O_NONBLOCK );
|
||||
|
||||
log_v("Seeding the random number generator");
|
||||
mbedtls_entropy_init(&ssl_client->entropy_ctx);
|
||||
|
||||
ret = mbedtls_ctr_drbg_seed(&ssl_client->drbg_ctx, mbedtls_entropy_func,
|
||||
&ssl_client->entropy_ctx, (const unsigned char *) pers, strlen(pers));
|
||||
if (ret < 0) {
|
||||
return handle_error(ret);
|
||||
}
|
||||
|
||||
log_v("Setting up the SSL/TLS structure...");
|
||||
|
||||
if ((ret = mbedtls_ssl_config_defaults(&ssl_client->ssl_conf,
|
||||
MBEDTLS_SSL_IS_CLIENT,
|
||||
MBEDTLS_SSL_TRANSPORT_STREAM,
|
||||
MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
|
||||
return handle_error(ret);
|
||||
}
|
||||
|
||||
// MBEDTLS_SSL_VERIFY_REQUIRED if a CA certificate is defined on Arduino IDE and
|
||||
// MBEDTLS_SSL_VERIFY_NONE if not.
|
||||
|
||||
if (rootCABuff != NULL) {
|
||||
log_v("Loading CA cert");
|
||||
mbedtls_x509_crt_init(&ssl_client->ca_cert);
|
||||
mbedtls_ssl_conf_authmode(&ssl_client->ssl_conf, MBEDTLS_SSL_VERIFY_REQUIRED);
|
||||
ret = mbedtls_x509_crt_parse(&ssl_client->ca_cert, (const unsigned char *)rootCABuff, strlen(rootCABuff) + 1);
|
||||
mbedtls_ssl_conf_ca_chain(&ssl_client->ssl_conf, &ssl_client->ca_cert, NULL);
|
||||
//mbedtls_ssl_conf_verify(&ssl_client->ssl_ctx, my_verify, NULL );
|
||||
if (ret < 0) {
|
||||
return handle_error(ret);
|
||||
}
|
||||
} else {
|
||||
mbedtls_ssl_conf_authmode(&ssl_client->ssl_conf, MBEDTLS_SSL_VERIFY_NONE);
|
||||
log_i("WARNING: Use certificates for a more secure communication!");
|
||||
}
|
||||
|
||||
if (cli_cert != NULL && cli_key != NULL) {
|
||||
mbedtls_x509_crt_init(&ssl_client->client_cert);
|
||||
mbedtls_pk_init(&ssl_client->client_key);
|
||||
|
||||
log_v("Loading CRT cert");
|
||||
|
||||
ret = mbedtls_x509_crt_parse(&ssl_client->client_cert, (const unsigned char *)cli_cert, strlen(cli_cert) + 1);
|
||||
if (ret < 0) {
|
||||
return handle_error(ret);
|
||||
}
|
||||
|
||||
log_v("Loading private key");
|
||||
ret = mbedtls_pk_parse_key(&ssl_client->client_key, (const unsigned char *)cli_key, strlen(cli_key) + 1, NULL, 0);
|
||||
|
||||
if (ret != 0) {
|
||||
return handle_error(ret);
|
||||
}
|
||||
|
||||
mbedtls_ssl_conf_own_cert(&ssl_client->ssl_conf, &ssl_client->client_cert, &ssl_client->client_key);
|
||||
}
|
||||
|
||||
log_v("Setting hostname for TLS session...");
|
||||
|
||||
// Hostname set here should match CN in server certificate
|
||||
if((ret = mbedtls_ssl_set_hostname(&ssl_client->ssl_ctx, host)) != 0){
|
||||
return handle_error(ret);
|
||||
}
|
||||
|
||||
mbedtls_ssl_conf_rng(&ssl_client->ssl_conf, mbedtls_ctr_drbg_random, &ssl_client->drbg_ctx);
|
||||
|
||||
if ((ret = mbedtls_ssl_setup(&ssl_client->ssl_ctx, &ssl_client->ssl_conf)) != 0) {
|
||||
return handle_error(ret);
|
||||
}
|
||||
|
||||
mbedtls_ssl_set_bio(&ssl_client->ssl_ctx, &ssl_client->socket, mbedtls_net_send, mbedtls_net_recv, NULL );
|
||||
|
||||
log_v("Performing the SSL/TLS handshake...");
|
||||
|
||||
while ((ret = mbedtls_ssl_handshake(&ssl_client->ssl_ctx)) != 0) {
|
||||
if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
|
||||
return handle_error(ret);
|
||||
}
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||
}
|
||||
|
||||
|
||||
if (cli_cert != NULL && cli_key != NULL) {
|
||||
log_d("Protocol is %s Ciphersuite is %s", mbedtls_ssl_get_version(&ssl_client->ssl_ctx), mbedtls_ssl_get_ciphersuite(&ssl_client->ssl_ctx));
|
||||
if ((ret = mbedtls_ssl_get_record_expansion(&ssl_client->ssl_ctx)) >= 0) {
|
||||
log_d("Record expansion is %d", ret);
|
||||
} else {
|
||||
log_w("Record expansion is unknown (compression)");
|
||||
}
|
||||
}
|
||||
|
||||
log_v("Verifying peer X.509 certificate...");
|
||||
|
||||
if ((flags = mbedtls_ssl_get_verify_result(&ssl_client->ssl_ctx)) != 0) {
|
||||
bzero(buf, sizeof(buf));
|
||||
mbedtls_x509_crt_verify_info(buf, sizeof(buf), " ! ", flags);
|
||||
log_e("Failed to verify peer certificate! verification info: %s", buf);
|
||||
stop_ssl_socket(ssl_client, rootCABuff, cli_cert, cli_key); //It's not safe continue.
|
||||
return handle_error(ret);
|
||||
} else {
|
||||
log_v("Certificate verified.");
|
||||
}
|
||||
|
||||
if (rootCABuff != NULL) {
|
||||
mbedtls_x509_crt_free(&ssl_client->ca_cert);
|
||||
}
|
||||
|
||||
if (cli_cert != NULL) {
|
||||
mbedtls_x509_crt_free(&ssl_client->client_cert);
|
||||
}
|
||||
|
||||
if (cli_key != NULL) {
|
||||
mbedtls_pk_free(&ssl_client->client_key);
|
||||
}
|
||||
|
||||
log_v("Free heap after TLS %u", xPortGetFreeHeapSize());
|
||||
|
||||
return ssl_client->socket;
|
||||
}
|
||||
|
||||
|
||||
void stop_ssl_socket(sslclient_context *ssl_client, const char *rootCABuff, const char *cli_cert, const char *cli_key)
|
||||
{
|
||||
log_v("Cleaning SSL connection.");
|
||||
|
||||
if (ssl_client->socket >= 0) {
|
||||
close(ssl_client->socket);
|
||||
ssl_client->socket = -1;
|
||||
}
|
||||
|
||||
mbedtls_ssl_free(&ssl_client->ssl_ctx);
|
||||
mbedtls_ssl_config_free(&ssl_client->ssl_conf);
|
||||
mbedtls_ctr_drbg_free(&ssl_client->drbg_ctx);
|
||||
mbedtls_entropy_free(&ssl_client->entropy_ctx);
|
||||
}
|
||||
|
||||
|
||||
int data_to_read(sslclient_context *ssl_client)
|
||||
{
|
||||
int ret, res;
|
||||
ret = mbedtls_ssl_read(&ssl_client->ssl_ctx, NULL, 0);
|
||||
//log_e("RET: %i",ret); //for low level debug
|
||||
res = mbedtls_ssl_get_bytes_avail(&ssl_client->ssl_ctx);
|
||||
//log_e("RES: %i",res); //for low level debug
|
||||
if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE && ret < 0) {
|
||||
return handle_error(ret);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
int send_ssl_data(sslclient_context *ssl_client, const uint8_t *data, uint16_t len)
|
||||
{
|
||||
log_v("Writing HTTP request..."); //for low level debug
|
||||
int ret = -1;
|
||||
|
||||
while ((ret = mbedtls_ssl_write(&ssl_client->ssl_ctx, data, len)) <= 0) {
|
||||
if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
|
||||
return handle_error(ret);
|
||||
}
|
||||
}
|
||||
|
||||
len = ret;
|
||||
//log_v("%d bytes written", len); //for low level debug
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int get_ssl_receive(sslclient_context *ssl_client, uint8_t *data, int length)
|
||||
{
|
||||
//log_d( "Reading HTTP response..."); //for low level debug
|
||||
int ret = -1;
|
||||
|
||||
ret = mbedtls_ssl_read(&ssl_client->ssl_ctx, data, length);
|
||||
|
||||
//log_v( "%d bytes read", ret); //for low level debug
|
||||
return ret;
|
||||
}
|
||||
/* Provide SSL/TLS functions to ESP32 with Arduino IDE
|
||||
*
|
||||
* Adapted from the ssl_client1 example of mbedtls.
|
||||
*
|
||||
* Original Copyright (C) 2006-2015, ARM Limited, All Rights Reserved, Apache 2.0 License.
|
||||
* Additions Copyright (C) 2017 Evandro Luis Copercini, Apache 2.0 License.
|
||||
*/
|
||||
|
||||
#include "Arduino.h"
|
||||
#include <esp32-hal-log.h>
|
||||
#include <lwip/err.h>
|
||||
#include <lwip/sockets.h>
|
||||
#include <lwip/sys.h>
|
||||
#include <lwip/netdb.h>
|
||||
#include "ssl_client.h"
|
||||
|
||||
|
||||
const char *pers = "esp32-tls";
|
||||
|
||||
static int handle_error(int err)
|
||||
{
|
||||
if(err == -30848){
|
||||
return err;
|
||||
}
|
||||
#ifdef MBEDTLS_ERROR_C
|
||||
char error_buf[100];
|
||||
mbedtls_strerror(err, error_buf, 100);
|
||||
log_e("%s", error_buf);
|
||||
#endif
|
||||
log_e("MbedTLS message code: %d", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
void ssl_init(sslclient_context *ssl_client)
|
||||
{
|
||||
mbedtls_ssl_init(&ssl_client->ssl_ctx);
|
||||
mbedtls_ssl_config_init(&ssl_client->ssl_conf);
|
||||
mbedtls_ctr_drbg_init(&ssl_client->drbg_ctx);
|
||||
}
|
||||
|
||||
|
||||
int start_ssl_client(sslclient_context *ssl_client, const char *host, uint32_t port, const char *rootCABuff, const char *cli_cert, const char *cli_key)
|
||||
{
|
||||
char buf[512];
|
||||
int ret, flags, timeout;
|
||||
int enable = 1;
|
||||
log_v("Free heap before TLS %u", xPortGetFreeHeapSize());
|
||||
|
||||
log_v("Starting socket");
|
||||
ssl_client->socket = -1;
|
||||
|
||||
ssl_client->socket = lwip_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (ssl_client->socket < 0) {
|
||||
log_e("ERROR opening socket");
|
||||
return ssl_client->socket;
|
||||
}
|
||||
|
||||
struct hostent *server;
|
||||
server = gethostbyname(host);
|
||||
if (server == NULL) {
|
||||
log_e("gethostbyname failed");
|
||||
return -1;
|
||||
}
|
||||
IPAddress srv((const uint8_t *)(server->h_addr));
|
||||
|
||||
struct sockaddr_in serv_addr;
|
||||
memset(&serv_addr, 0, sizeof(serv_addr));
|
||||
serv_addr.sin_family = AF_INET;
|
||||
serv_addr.sin_addr.s_addr = srv;
|
||||
serv_addr.sin_port = htons(port);
|
||||
|
||||
if (lwip_connect(ssl_client->socket, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == 0) {
|
||||
timeout = 30000;
|
||||
lwip_setsockopt(ssl_client->socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
|
||||
lwip_setsockopt(ssl_client->socket, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
|
||||
lwip_setsockopt(ssl_client->socket, IPPROTO_TCP, TCP_NODELAY, &enable, sizeof(enable));
|
||||
lwip_setsockopt(ssl_client->socket, SOL_SOCKET, SO_KEEPALIVE, &enable, sizeof(enable));
|
||||
} else {
|
||||
log_e("Connect to Server failed!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fcntl( ssl_client->socket, F_SETFL, fcntl( ssl_client->socket, F_GETFL, 0 ) | O_NONBLOCK );
|
||||
|
||||
log_v("Seeding the random number generator");
|
||||
mbedtls_entropy_init(&ssl_client->entropy_ctx);
|
||||
|
||||
ret = mbedtls_ctr_drbg_seed(&ssl_client->drbg_ctx, mbedtls_entropy_func,
|
||||
&ssl_client->entropy_ctx, (const unsigned char *) pers, strlen(pers));
|
||||
if (ret < 0) {
|
||||
return handle_error(ret);
|
||||
}
|
||||
|
||||
log_v("Setting up the SSL/TLS structure...");
|
||||
|
||||
if ((ret = mbedtls_ssl_config_defaults(&ssl_client->ssl_conf,
|
||||
MBEDTLS_SSL_IS_CLIENT,
|
||||
MBEDTLS_SSL_TRANSPORT_STREAM,
|
||||
MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
|
||||
return handle_error(ret);
|
||||
}
|
||||
|
||||
// MBEDTLS_SSL_VERIFY_REQUIRED if a CA certificate is defined on Arduino IDE and
|
||||
// MBEDTLS_SSL_VERIFY_NONE if not.
|
||||
|
||||
if (rootCABuff != NULL) {
|
||||
log_v("Loading CA cert");
|
||||
mbedtls_x509_crt_init(&ssl_client->ca_cert);
|
||||
mbedtls_ssl_conf_authmode(&ssl_client->ssl_conf, MBEDTLS_SSL_VERIFY_REQUIRED);
|
||||
ret = mbedtls_x509_crt_parse(&ssl_client->ca_cert, (const unsigned char *)rootCABuff, strlen(rootCABuff) + 1);
|
||||
mbedtls_ssl_conf_ca_chain(&ssl_client->ssl_conf, &ssl_client->ca_cert, NULL);
|
||||
//mbedtls_ssl_conf_verify(&ssl_client->ssl_ctx, my_verify, NULL );
|
||||
if (ret < 0) {
|
||||
return handle_error(ret);
|
||||
}
|
||||
} else {
|
||||
mbedtls_ssl_conf_authmode(&ssl_client->ssl_conf, MBEDTLS_SSL_VERIFY_NONE);
|
||||
log_i("WARNING: Use certificates for a more secure communication!");
|
||||
}
|
||||
|
||||
if (cli_cert != NULL && cli_key != NULL) {
|
||||
mbedtls_x509_crt_init(&ssl_client->client_cert);
|
||||
mbedtls_pk_init(&ssl_client->client_key);
|
||||
|
||||
log_v("Loading CRT cert");
|
||||
|
||||
ret = mbedtls_x509_crt_parse(&ssl_client->client_cert, (const unsigned char *)cli_cert, strlen(cli_cert) + 1);
|
||||
if (ret < 0) {
|
||||
return handle_error(ret);
|
||||
}
|
||||
|
||||
log_v("Loading private key");
|
||||
ret = mbedtls_pk_parse_key(&ssl_client->client_key, (const unsigned char *)cli_key, strlen(cli_key) + 1, NULL, 0);
|
||||
|
||||
if (ret != 0) {
|
||||
return handle_error(ret);
|
||||
}
|
||||
|
||||
mbedtls_ssl_conf_own_cert(&ssl_client->ssl_conf, &ssl_client->client_cert, &ssl_client->client_key);
|
||||
}
|
||||
|
||||
log_v("Setting hostname for TLS session...");
|
||||
|
||||
// Hostname set here should match CN in server certificate
|
||||
if((ret = mbedtls_ssl_set_hostname(&ssl_client->ssl_ctx, host)) != 0){
|
||||
return handle_error(ret);
|
||||
}
|
||||
|
||||
mbedtls_ssl_conf_rng(&ssl_client->ssl_conf, mbedtls_ctr_drbg_random, &ssl_client->drbg_ctx);
|
||||
|
||||
if ((ret = mbedtls_ssl_setup(&ssl_client->ssl_ctx, &ssl_client->ssl_conf)) != 0) {
|
||||
return handle_error(ret);
|
||||
}
|
||||
|
||||
mbedtls_ssl_set_bio(&ssl_client->ssl_ctx, &ssl_client->socket, mbedtls_net_send, mbedtls_net_recv, NULL );
|
||||
|
||||
log_v("Performing the SSL/TLS handshake...");
|
||||
|
||||
while ((ret = mbedtls_ssl_handshake(&ssl_client->ssl_ctx)) != 0) {
|
||||
if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
|
||||
return handle_error(ret);
|
||||
}
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||
}
|
||||
|
||||
|
||||
if (cli_cert != NULL && cli_key != NULL) {
|
||||
log_d("Protocol is %s Ciphersuite is %s", mbedtls_ssl_get_version(&ssl_client->ssl_ctx), mbedtls_ssl_get_ciphersuite(&ssl_client->ssl_ctx));
|
||||
if ((ret = mbedtls_ssl_get_record_expansion(&ssl_client->ssl_ctx)) >= 0) {
|
||||
log_d("Record expansion is %d", ret);
|
||||
} else {
|
||||
log_w("Record expansion is unknown (compression)");
|
||||
}
|
||||
}
|
||||
|
||||
log_v("Verifying peer X.509 certificate...");
|
||||
|
||||
if ((flags = mbedtls_ssl_get_verify_result(&ssl_client->ssl_ctx)) != 0) {
|
||||
bzero(buf, sizeof(buf));
|
||||
mbedtls_x509_crt_verify_info(buf, sizeof(buf), " ! ", flags);
|
||||
log_e("Failed to verify peer certificate! verification info: %s", buf);
|
||||
stop_ssl_socket(ssl_client, rootCABuff, cli_cert, cli_key); //It's not safe continue.
|
||||
return handle_error(ret);
|
||||
} else {
|
||||
log_v("Certificate verified.");
|
||||
}
|
||||
|
||||
if (rootCABuff != NULL) {
|
||||
mbedtls_x509_crt_free(&ssl_client->ca_cert);
|
||||
}
|
||||
|
||||
if (cli_cert != NULL) {
|
||||
mbedtls_x509_crt_free(&ssl_client->client_cert);
|
||||
}
|
||||
|
||||
if (cli_key != NULL) {
|
||||
mbedtls_pk_free(&ssl_client->client_key);
|
||||
}
|
||||
|
||||
log_v("Free heap after TLS %u", xPortGetFreeHeapSize());
|
||||
|
||||
return ssl_client->socket;
|
||||
}
|
||||
|
||||
|
||||
void stop_ssl_socket(sslclient_context *ssl_client, const char *rootCABuff, const char *cli_cert, const char *cli_key)
|
||||
{
|
||||
log_v("Cleaning SSL connection.");
|
||||
|
||||
if (ssl_client->socket >= 0) {
|
||||
close(ssl_client->socket);
|
||||
ssl_client->socket = -1;
|
||||
}
|
||||
|
||||
mbedtls_ssl_free(&ssl_client->ssl_ctx);
|
||||
mbedtls_ssl_config_free(&ssl_client->ssl_conf);
|
||||
mbedtls_ctr_drbg_free(&ssl_client->drbg_ctx);
|
||||
mbedtls_entropy_free(&ssl_client->entropy_ctx);
|
||||
}
|
||||
|
||||
|
||||
int data_to_read(sslclient_context *ssl_client)
|
||||
{
|
||||
int ret, res;
|
||||
ret = mbedtls_ssl_read(&ssl_client->ssl_ctx, NULL, 0);
|
||||
//log_e("RET: %i",ret); //for low level debug
|
||||
res = mbedtls_ssl_get_bytes_avail(&ssl_client->ssl_ctx);
|
||||
//log_e("RES: %i",res); //for low level debug
|
||||
if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE && ret < 0) {
|
||||
return handle_error(ret);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
int send_ssl_data(sslclient_context *ssl_client, const uint8_t *data, uint16_t len)
|
||||
{
|
||||
log_v("Writing HTTP request..."); //for low level debug
|
||||
int ret = -1;
|
||||
|
||||
while ((ret = mbedtls_ssl_write(&ssl_client->ssl_ctx, data, len)) <= 0) {
|
||||
if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
|
||||
return handle_error(ret);
|
||||
}
|
||||
}
|
||||
|
||||
len = ret;
|
||||
//log_v("%d bytes written", len); //for low level debug
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int get_ssl_receive(sslclient_context *ssl_client, uint8_t *data, int length)
|
||||
{
|
||||
//log_d( "Reading HTTP response..."); //for low level debug
|
||||
int ret = -1;
|
||||
|
||||
ret = mbedtls_ssl_read(&ssl_client->ssl_ctx, data, length);
|
||||
|
||||
//log_v( "%d bytes read", ret); //for low level debug
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,36 +1,36 @@
|
||||
/* Provide SSL/TLS functions to ESP32 with Arduino IDE
|
||||
* by Evandro Copercini - 2017 - Apache 2.0 License
|
||||
*/
|
||||
|
||||
#ifndef ARD_SSL_H
|
||||
#define ARD_SSL_H
|
||||
#include "mbedtls/platform.h"
|
||||
#include "mbedtls/net.h"
|
||||
#include "mbedtls/debug.h"
|
||||
#include "mbedtls/ssl.h"
|
||||
#include "mbedtls/entropy.h"
|
||||
#include "mbedtls/ctr_drbg.h"
|
||||
#include "mbedtls/error.h"
|
||||
|
||||
typedef struct sslclient_context {
|
||||
int socket;
|
||||
mbedtls_ssl_context ssl_ctx;
|
||||
mbedtls_ssl_config ssl_conf;
|
||||
|
||||
mbedtls_ctr_drbg_context drbg_ctx;
|
||||
mbedtls_entropy_context entropy_ctx;
|
||||
|
||||
mbedtls_x509_crt ca_cert;
|
||||
mbedtls_x509_crt client_cert;
|
||||
mbedtls_pk_context client_key;
|
||||
} sslclient_context;
|
||||
|
||||
|
||||
void ssl_init(sslclient_context *ssl_client);
|
||||
int start_ssl_client(sslclient_context *ssl_client, const char *host, uint32_t port, const char *rootCABuff, const char *cli_cert, const char *cli_key);
|
||||
void stop_ssl_socket(sslclient_context *ssl_client, const char *rootCABuff, const char *cli_cert, const char *cli_key);
|
||||
int data_to_read(sslclient_context *ssl_client);
|
||||
int send_ssl_data(sslclient_context *ssl_client, const uint8_t *data, uint16_t len);
|
||||
int get_ssl_receive(sslclient_context *ssl_client, uint8_t *data, int length);
|
||||
|
||||
#endif
|
||||
/* Provide SSL/TLS functions to ESP32 with Arduino IDE
|
||||
* by Evandro Copercini - 2017 - Apache 2.0 License
|
||||
*/
|
||||
|
||||
#ifndef ARD_SSL_H
|
||||
#define ARD_SSL_H
|
||||
#include "mbedtls/platform.h"
|
||||
#include "mbedtls/net.h"
|
||||
#include "mbedtls/debug.h"
|
||||
#include "mbedtls/ssl.h"
|
||||
#include "mbedtls/entropy.h"
|
||||
#include "mbedtls/ctr_drbg.h"
|
||||
#include "mbedtls/error.h"
|
||||
|
||||
typedef struct sslclient_context {
|
||||
int socket;
|
||||
mbedtls_ssl_context ssl_ctx;
|
||||
mbedtls_ssl_config ssl_conf;
|
||||
|
||||
mbedtls_ctr_drbg_context drbg_ctx;
|
||||
mbedtls_entropy_context entropy_ctx;
|
||||
|
||||
mbedtls_x509_crt ca_cert;
|
||||
mbedtls_x509_crt client_cert;
|
||||
mbedtls_pk_context client_key;
|
||||
} sslclient_context;
|
||||
|
||||
|
||||
void ssl_init(sslclient_context *ssl_client);
|
||||
int start_ssl_client(sslclient_context *ssl_client, const char *host, uint32_t port, const char *rootCABuff, const char *cli_cert, const char *cli_key);
|
||||
void stop_ssl_socket(sslclient_context *ssl_client, const char *rootCABuff, const char *cli_cert, const char *cli_key);
|
||||
int data_to_read(sslclient_context *ssl_client);
|
||||
int send_ssl_data(sslclient_context *ssl_client, const uint8_t *data, uint16_t len);
|
||||
int get_ssl_receive(sslclient_context *ssl_client, uint8_t *data, int length);
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,120 +1,120 @@
|
||||
|
||||
// Copyright (c) 2003-2015 Cadence Design Systems, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
// a copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
// permit persons to whom the Software is furnished to do so, subject to
|
||||
// the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
#ifndef __XOS_INTERNAL_H__
|
||||
#define __XOS_INTERNAL_H__
|
||||
|
||||
#if !defined(__XOS_H__) || !defined(_XOS_INCLUDE_INTERNAL_)
|
||||
#error "xos_internal.h must be included by defining _XOS_INCLUDE_INTERNAL_ before including xos.h"
|
||||
#endif
|
||||
|
||||
#include <xtensa/config/core.h>
|
||||
#include "xos_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
// Use this macro to suppress compiler warnings for unused variables.
|
||||
|
||||
#define UNUSED(x) (void)(x)
|
||||
|
||||
|
||||
#if XOS_DEBUG
|
||||
|
||||
#include <stdio.h>
|
||||
#include <xtensa/xtutil.h>
|
||||
# define DPRINTF printf
|
||||
|
||||
#else
|
||||
|
||||
# define DPRINTF(x...) do {} while(0)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Internal flags for thread creation.
|
||||
//-----------------------------------------------------------------------------
|
||||
#define XOS_THREAD_FAKE 0x8000 // Don't allocate stack (init and idle threads).
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Interrupt handler table entry. This structure defines one entry in the XOS
|
||||
// interrupt handler table.
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef struct XosIntEntry {
|
||||
XosIntFunc * handler; // Pointer to handler function.
|
||||
void * arg; // Argument passed to handler function.
|
||||
#if XOS_OPT_INTERRUPT_SWPRI
|
||||
unsigned char level; // Interrupt level.
|
||||
unsigned char priority; // Interrupt priority.
|
||||
short reserved; // Reserved.
|
||||
unsigned int primask; // Mask of interrupts at higher priority.
|
||||
#else
|
||||
unsigned int ps; // Value of PS when running the handler.
|
||||
#endif
|
||||
} XosIntEntry;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Extern variables.
|
||||
//-----------------------------------------------------------------------------
|
||||
extern unsigned xos_intlevel_mask;
|
||||
extern unsigned xos_intenable_mask;
|
||||
extern XosIntEntry xos_interrupt_table[XCHAL_NUM_INTERRUPTS];
|
||||
|
||||
extern uint32_t xos_clock_freq;
|
||||
extern uint32_t xos_tick_period;
|
||||
extern uint64_t xos_system_ticks;
|
||||
extern uint64_t xos_system_cycles;
|
||||
extern uint32_t xos_num_ctx_switches;
|
||||
|
||||
|
||||
/*
|
||||
|
||||
One thing I noticed is different between my initial idea of stack
|
||||
assignments to RTC threads, when comparing to interrupts, is that I
|
||||
expected each RTC thread priority to have its own stack, whereas
|
||||
interrupts of different priorities share an interrupt stack.
|
||||
|
||||
It's not really a difference in memory usage, because when assigning
|
||||
multiple priorities to a stack, you have to add-up worst-case for
|
||||
all priorities. One possible functional difference is that with
|
||||
separate stacks per priority, it's possible to dynamically change
|
||||
the priority of an RTC thread (while it's running). Not sure how
|
||||
valuable that might be -- changing priority is useful with priority
|
||||
inheritance, to avoid priority inversion, but I don't know how often
|
||||
an RTC thread might acquire a lock (it couldn't block on acquiring a
|
||||
lock in the usual sense -- it could get queued waiting and be restarted
|
||||
when it becomes available, or use try_lock instead of lock).
|
||||
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __XOS_INTERNAL_H__ */
|
||||
|
||||
|
||||
// Copyright (c) 2003-2015 Cadence Design Systems, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
// a copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
// permit persons to whom the Software is furnished to do so, subject to
|
||||
// the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
#ifndef __XOS_INTERNAL_H__
|
||||
#define __XOS_INTERNAL_H__
|
||||
|
||||
#if !defined(__XOS_H__) || !defined(_XOS_INCLUDE_INTERNAL_)
|
||||
#error "xos_internal.h must be included by defining _XOS_INCLUDE_INTERNAL_ before including xos.h"
|
||||
#endif
|
||||
|
||||
#include <xtensa/config/core.h>
|
||||
#include "xos_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
// Use this macro to suppress compiler warnings for unused variables.
|
||||
|
||||
#define UNUSED(x) (void)(x)
|
||||
|
||||
|
||||
#if XOS_DEBUG
|
||||
|
||||
#include <stdio.h>
|
||||
#include <xtensa/xtutil.h>
|
||||
# define DPRINTF printf
|
||||
|
||||
#else
|
||||
|
||||
# define DPRINTF(x...) do {} while(0)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Internal flags for thread creation.
|
||||
//-----------------------------------------------------------------------------
|
||||
#define XOS_THREAD_FAKE 0x8000 // Don't allocate stack (init and idle threads).
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Interrupt handler table entry. This structure defines one entry in the XOS
|
||||
// interrupt handler table.
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef struct XosIntEntry {
|
||||
XosIntFunc * handler; // Pointer to handler function.
|
||||
void * arg; // Argument passed to handler function.
|
||||
#if XOS_OPT_INTERRUPT_SWPRI
|
||||
unsigned char level; // Interrupt level.
|
||||
unsigned char priority; // Interrupt priority.
|
||||
short reserved; // Reserved.
|
||||
unsigned int primask; // Mask of interrupts at higher priority.
|
||||
#else
|
||||
unsigned int ps; // Value of PS when running the handler.
|
||||
#endif
|
||||
} XosIntEntry;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Extern variables.
|
||||
//-----------------------------------------------------------------------------
|
||||
extern unsigned xos_intlevel_mask;
|
||||
extern unsigned xos_intenable_mask;
|
||||
extern XosIntEntry xos_interrupt_table[XCHAL_NUM_INTERRUPTS];
|
||||
|
||||
extern uint32_t xos_clock_freq;
|
||||
extern uint32_t xos_tick_period;
|
||||
extern uint64_t xos_system_ticks;
|
||||
extern uint64_t xos_system_cycles;
|
||||
extern uint32_t xos_num_ctx_switches;
|
||||
|
||||
|
||||
/*
|
||||
|
||||
One thing I noticed is different between my initial idea of stack
|
||||
assignments to RTC threads, when comparing to interrupts, is that I
|
||||
expected each RTC thread priority to have its own stack, whereas
|
||||
interrupts of different priorities share an interrupt stack.
|
||||
|
||||
It's not really a difference in memory usage, because when assigning
|
||||
multiple priorities to a stack, you have to add-up worst-case for
|
||||
all priorities. One possible functional difference is that with
|
||||
separate stacks per priority, it's possible to dynamically change
|
||||
the priority of an RTC thread (while it's running). Not sure how
|
||||
valuable that might be -- changing priority is useful with priority
|
||||
inheritance, to avoid priority inversion, but I don't know how often
|
||||
an RTC thread might acquire a lock (it couldn't block on acquiring a
|
||||
lock in the usual sense -- it could get queued waiting and be restarted
|
||||
when it becomes available, or use try_lock instead of lock).
|
||||
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __XOS_INTERNAL_H__ */
|
||||
|
||||
|
@ -1,133 +1,133 @@
|
||||
/*-----------------------------------------------------------------------/
|
||||
/ Low level disk interface modlue include file (C)ChaN, 2014 /
|
||||
/-----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _DISKIO_DEFINED
|
||||
#define _DISKIO_DEFINED
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "integer.h"
|
||||
#include "sdmmc_cmd.h"
|
||||
#include "driver/sdmmc_host.h"
|
||||
|
||||
/* Status of Disk Functions */
|
||||
typedef BYTE DSTATUS;
|
||||
|
||||
/* Results of Disk Functions */
|
||||
typedef enum {
|
||||
RES_OK = 0, /* 0: Successful */
|
||||
RES_ERROR, /* 1: R/W Error */
|
||||
RES_WRPRT, /* 2: Write Protected */
|
||||
RES_NOTRDY, /* 3: Not Ready */
|
||||
RES_PARERR /* 4: Invalid Parameter */
|
||||
} DRESULT;
|
||||
|
||||
|
||||
/*---------------------------------------*/
|
||||
/* Prototypes for disk control functions */
|
||||
|
||||
|
||||
/* Redefine names of disk IO functions to prevent name collisions */
|
||||
#define disk_initialize ff_disk_initialize
|
||||
#define disk_status ff_disk_status
|
||||
#define disk_read ff_disk_read
|
||||
#define disk_write ff_disk_write
|
||||
#define disk_ioctl ff_disk_ioctl
|
||||
|
||||
|
||||
DSTATUS disk_initialize (BYTE pdrv);
|
||||
DSTATUS disk_status (BYTE pdrv);
|
||||
DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
|
||||
DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
|
||||
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
|
||||
|
||||
/**
|
||||
* Structure of pointers to disk IO driver functions.
|
||||
*
|
||||
* See FatFs documentation for details about these functions
|
||||
*/
|
||||
typedef struct {
|
||||
DSTATUS (*init) (BYTE pdrv); /*!< disk initialization function */
|
||||
DSTATUS (*status) (BYTE pdrv); /*!< disk status check function */
|
||||
DRESULT (*read) (BYTE pdrv, BYTE* buff, DWORD sector, UINT count); /*!< sector read function */
|
||||
DRESULT (*write) (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count); /*!< sector write function */
|
||||
DRESULT (*ioctl) (BYTE pdrv, BYTE cmd, void* buff); /*!< function to get info about disk and do some misc operations */
|
||||
} ff_diskio_impl_t;
|
||||
|
||||
/**
|
||||
* Register or unregister diskio driver for given drive number.
|
||||
*
|
||||
* When FATFS library calls one of disk_xxx functions for driver number pdrv,
|
||||
* corresponding function in discio_impl for given pdrv will be called.
|
||||
*
|
||||
* @param pdrv drive number
|
||||
* @param discio_impl pointer to ff_diskio_impl_t structure with diskio functions
|
||||
* or NULL to unregister and free previously registered drive
|
||||
*/
|
||||
void ff_diskio_register(BYTE pdrv, const ff_diskio_impl_t* discio_impl);
|
||||
|
||||
#define ff_diskio_unregister(pdrv_) ff_diskio_register(pdrv_, NULL)
|
||||
|
||||
/**
|
||||
* Register SD/MMC diskio driver
|
||||
*
|
||||
* @param pdrv drive number
|
||||
* @param card pointer to sdmmc_card_t structure describing a card; card should be initialized before calling f_mount.
|
||||
*/
|
||||
void ff_diskio_register_sdmmc(BYTE pdrv, sdmmc_card_t* card);
|
||||
|
||||
/**
|
||||
* Get next available drive number
|
||||
*
|
||||
* @param out_pdrv pointer to the byte to set if successful
|
||||
*
|
||||
* @return ESP_OK on success
|
||||
* ESP_ERR_NOT_FOUND if all drives are attached
|
||||
*/
|
||||
esp_err_t ff_diskio_get_drive(BYTE* out_pdrv);
|
||||
|
||||
/* Disk Status Bits (DSTATUS) */
|
||||
|
||||
#define STA_NOINIT 0x01 /* Drive not initialized */
|
||||
#define STA_NODISK 0x02 /* No medium in the drive */
|
||||
#define STA_PROTECT 0x04 /* Write protected */
|
||||
|
||||
|
||||
/* Command code for disk_ioctrl fucntion */
|
||||
|
||||
/* Generic command (Used by FatFs) */
|
||||
#define CTRL_SYNC 0 /* Complete pending write process (needed at _FS_READONLY == 0) */
|
||||
#define GET_SECTOR_COUNT 1 /* Get media size (needed at _USE_MKFS == 1) */
|
||||
#define GET_SECTOR_SIZE 2 /* Get sector size (needed at _MAX_SS != _MIN_SS) */
|
||||
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at _USE_MKFS == 1) */
|
||||
#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at _USE_TRIM == 1) */
|
||||
|
||||
/* Generic command (Not used by FatFs) */
|
||||
#define CTRL_POWER 5 /* Get/Set power status */
|
||||
#define CTRL_LOCK 6 /* Lock/Unlock media removal */
|
||||
#define CTRL_EJECT 7 /* Eject media */
|
||||
#define CTRL_FORMAT 8 /* Create physical format on the media */
|
||||
|
||||
/* MMC/SDC specific ioctl command */
|
||||
#define MMC_GET_TYPE 10 /* Get card type */
|
||||
#define MMC_GET_CSD 11 /* Get CSD */
|
||||
#define MMC_GET_CID 12 /* Get CID */
|
||||
#define MMC_GET_OCR 13 /* Get OCR */
|
||||
#define MMC_GET_SDSTAT 14 /* Get SD status */
|
||||
#define ISDIO_READ 55 /* Read data form SD iSDIO register */
|
||||
#define ISDIO_WRITE 56 /* Write data to SD iSDIO register */
|
||||
#define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */
|
||||
|
||||
/* ATA/CF specific ioctl command */
|
||||
#define ATA_GET_REV 20 /* Get F/W revision */
|
||||
#define ATA_GET_MODEL 21 /* Get model name */
|
||||
#define ATA_GET_SN 22 /* Get serial number */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/*-----------------------------------------------------------------------/
|
||||
/ Low level disk interface modlue include file (C)ChaN, 2014 /
|
||||
/-----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _DISKIO_DEFINED
|
||||
#define _DISKIO_DEFINED
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "integer.h"
|
||||
#include "sdmmc_cmd.h"
|
||||
#include "driver/sdmmc_host.h"
|
||||
|
||||
/* Status of Disk Functions */
|
||||
typedef BYTE DSTATUS;
|
||||
|
||||
/* Results of Disk Functions */
|
||||
typedef enum {
|
||||
RES_OK = 0, /* 0: Successful */
|
||||
RES_ERROR, /* 1: R/W Error */
|
||||
RES_WRPRT, /* 2: Write Protected */
|
||||
RES_NOTRDY, /* 3: Not Ready */
|
||||
RES_PARERR /* 4: Invalid Parameter */
|
||||
} DRESULT;
|
||||
|
||||
|
||||
/*---------------------------------------*/
|
||||
/* Prototypes for disk control functions */
|
||||
|
||||
|
||||
/* Redefine names of disk IO functions to prevent name collisions */
|
||||
#define disk_initialize ff_disk_initialize
|
||||
#define disk_status ff_disk_status
|
||||
#define disk_read ff_disk_read
|
||||
#define disk_write ff_disk_write
|
||||
#define disk_ioctl ff_disk_ioctl
|
||||
|
||||
|
||||
DSTATUS disk_initialize (BYTE pdrv);
|
||||
DSTATUS disk_status (BYTE pdrv);
|
||||
DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
|
||||
DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
|
||||
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
|
||||
|
||||
/**
|
||||
* Structure of pointers to disk IO driver functions.
|
||||
*
|
||||
* See FatFs documentation for details about these functions
|
||||
*/
|
||||
typedef struct {
|
||||
DSTATUS (*init) (BYTE pdrv); /*!< disk initialization function */
|
||||
DSTATUS (*status) (BYTE pdrv); /*!< disk status check function */
|
||||
DRESULT (*read) (BYTE pdrv, BYTE* buff, DWORD sector, UINT count); /*!< sector read function */
|
||||
DRESULT (*write) (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count); /*!< sector write function */
|
||||
DRESULT (*ioctl) (BYTE pdrv, BYTE cmd, void* buff); /*!< function to get info about disk and do some misc operations */
|
||||
} ff_diskio_impl_t;
|
||||
|
||||
/**
|
||||
* Register or unregister diskio driver for given drive number.
|
||||
*
|
||||
* When FATFS library calls one of disk_xxx functions for driver number pdrv,
|
||||
* corresponding function in discio_impl for given pdrv will be called.
|
||||
*
|
||||
* @param pdrv drive number
|
||||
* @param discio_impl pointer to ff_diskio_impl_t structure with diskio functions
|
||||
* or NULL to unregister and free previously registered drive
|
||||
*/
|
||||
void ff_diskio_register(BYTE pdrv, const ff_diskio_impl_t* discio_impl);
|
||||
|
||||
#define ff_diskio_unregister(pdrv_) ff_diskio_register(pdrv_, NULL)
|
||||
|
||||
/**
|
||||
* Register SD/MMC diskio driver
|
||||
*
|
||||
* @param pdrv drive number
|
||||
* @param card pointer to sdmmc_card_t structure describing a card; card should be initialized before calling f_mount.
|
||||
*/
|
||||
void ff_diskio_register_sdmmc(BYTE pdrv, sdmmc_card_t* card);
|
||||
|
||||
/**
|
||||
* Get next available drive number
|
||||
*
|
||||
* @param out_pdrv pointer to the byte to set if successful
|
||||
*
|
||||
* @return ESP_OK on success
|
||||
* ESP_ERR_NOT_FOUND if all drives are attached
|
||||
*/
|
||||
esp_err_t ff_diskio_get_drive(BYTE* out_pdrv);
|
||||
|
||||
/* Disk Status Bits (DSTATUS) */
|
||||
|
||||
#define STA_NOINIT 0x01 /* Drive not initialized */
|
||||
#define STA_NODISK 0x02 /* No medium in the drive */
|
||||
#define STA_PROTECT 0x04 /* Write protected */
|
||||
|
||||
|
||||
/* Command code for disk_ioctrl fucntion */
|
||||
|
||||
/* Generic command (Used by FatFs) */
|
||||
#define CTRL_SYNC 0 /* Complete pending write process (needed at _FS_READONLY == 0) */
|
||||
#define GET_SECTOR_COUNT 1 /* Get media size (needed at _USE_MKFS == 1) */
|
||||
#define GET_SECTOR_SIZE 2 /* Get sector size (needed at _MAX_SS != _MIN_SS) */
|
||||
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at _USE_MKFS == 1) */
|
||||
#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at _USE_TRIM == 1) */
|
||||
|
||||
/* Generic command (Not used by FatFs) */
|
||||
#define CTRL_POWER 5 /* Get/Set power status */
|
||||
#define CTRL_LOCK 6 /* Lock/Unlock media removal */
|
||||
#define CTRL_EJECT 7 /* Eject media */
|
||||
#define CTRL_FORMAT 8 /* Create physical format on the media */
|
||||
|
||||
/* MMC/SDC specific ioctl command */
|
||||
#define MMC_GET_TYPE 10 /* Get card type */
|
||||
#define MMC_GET_CSD 11 /* Get CSD */
|
||||
#define MMC_GET_CID 12 /* Get CID */
|
||||
#define MMC_GET_OCR 13 /* Get OCR */
|
||||
#define MMC_GET_SDSTAT 14 /* Get SD status */
|
||||
#define ISDIO_READ 55 /* Read data form SD iSDIO register */
|
||||
#define ISDIO_WRITE 56 /* Write data to SD iSDIO register */
|
||||
#define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */
|
||||
|
||||
/* ATA/CF specific ioctl command */
|
||||
#define ATA_GET_REV 20 /* Get F/W revision */
|
||||
#define ATA_GET_MODEL 21 /* Get model name */
|
||||
#define ATA_GET_SN 22 /* Get serial number */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -1,39 +1,39 @@
|
||||
// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _DISKIO_SPIFLASH_DEFINED
|
||||
#define _DISKIO_SPIFLASH_DEFINED
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "integer.h"
|
||||
#include "wear_levelling.h"
|
||||
|
||||
|
||||
/**
|
||||
* Register spi flash partition
|
||||
*
|
||||
* @param pdrv drive number
|
||||
* @param flash_handle handle of the wear levelling partition.
|
||||
*/
|
||||
esp_err_t ff_diskio_register_wl_partition(BYTE pdrv, wl_handle_t flash_handle);
|
||||
BYTE ff_diskio_get_pdrv_wl(wl_handle_t flash_handle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _DISKIO_SPIFLASH_DEFINED
|
||||
// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _DISKIO_SPIFLASH_DEFINED
|
||||
#define _DISKIO_SPIFLASH_DEFINED
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "integer.h"
|
||||
#include "wear_levelling.h"
|
||||
|
||||
|
||||
/**
|
||||
* Register spi flash partition
|
||||
*
|
||||
* @param pdrv drive number
|
||||
* @param flash_handle handle of the wear levelling partition.
|
||||
*/
|
||||
esp_err_t ff_diskio_register_wl_partition(BYTE pdrv, wl_handle_t flash_handle);
|
||||
BYTE ff_diskio_get_pdrv_wl(wl_handle_t flash_handle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _DISKIO_SPIFLASH_DEFINED
|
||||
|
@ -1,369 +1,369 @@
|
||||
/*----------------------------------------------------------------------------/
|
||||
/ FatFs - Generic FAT Filesystem module R0.13a /
|
||||
/-----------------------------------------------------------------------------/
|
||||
/
|
||||
/ Copyright (C) 2017, ChaN, all right reserved.
|
||||
/
|
||||
/ FatFs module is an open source software. Redistribution and use of FatFs in
|
||||
/ source and binary forms, with or without modification, are permitted provided
|
||||
/ that the following condition is met:
|
||||
|
||||
/ 1. Redistributions of source code must retain the above copyright notice,
|
||||
/ this condition and the following disclaimer.
|
||||
/
|
||||
/ This software is provided by the copyright holder and contributors "AS IS"
|
||||
/ and any warranties related to this software are DISCLAIMED.
|
||||
/ The copyright owner or contributors be NOT LIABLE for any damages caused
|
||||
/ by use of this software.
|
||||
/
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifndef FF_DEFINED
|
||||
#define FF_DEFINED 89352 /* Revision ID */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "integer.h" /* Basic integer types */
|
||||
#include "ffconf.h" /* FatFs configuration options */
|
||||
|
||||
#if FF_DEFINED != FFCONF_DEF
|
||||
#error Wrong configuration file (ffconf.h).
|
||||
#endif
|
||||
|
||||
#ifdef FF_DEFINE_DIR
|
||||
#define FF_DIR DIR
|
||||
#endif
|
||||
|
||||
|
||||
/* Definitions of volume management */
|
||||
|
||||
#if FF_MULTI_PARTITION /* Multiple partition configuration */
|
||||
typedef struct {
|
||||
BYTE pd; /* Physical drive number */
|
||||
BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
|
||||
} PARTITION;
|
||||
extern PARTITION VolToPart[]; /* Volume - Partition resolution table */
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Type of path name strings on FatFs API */
|
||||
|
||||
#ifndef _INC_TCHAR
|
||||
#define _INC_TCHAR
|
||||
|
||||
#if FF_USE_LFN && FF_LFN_UNICODE == 1 /* Unicode in UTF-16 encoding */
|
||||
typedef WCHAR TCHAR;
|
||||
#define _T(x) L ## x
|
||||
#define _TEXT(x) L ## x
|
||||
#elif FF_USE_LFN && FF_LFN_UNICODE == 2 /* Unicode in UTF-8 encoding */
|
||||
typedef char TCHAR;
|
||||
#define _T(x) u8 ## x
|
||||
#define _TEXT(x) u8 ## x
|
||||
#elif FF_USE_LFN && (FF_LFN_UNICODE < 0 || FF_LFN_UNICODE > 2)
|
||||
#error Wrong FF_LFN_UNICODE setting
|
||||
#else /* ANSI/OEM code in SBCS/DBCS */
|
||||
typedef char TCHAR;
|
||||
#define _T(x) x
|
||||
#define _TEXT(x) x
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Type of file size variables */
|
||||
|
||||
#if FF_FS_EXFAT
|
||||
typedef QWORD FSIZE_t;
|
||||
#else
|
||||
typedef DWORD FSIZE_t;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Filesystem object structure (FATFS) */
|
||||
|
||||
typedef struct {
|
||||
BYTE fs_type; /* Filesystem type (0:N/A) */
|
||||
BYTE pdrv; /* Physical drive number */
|
||||
BYTE n_fats; /* Number of FATs (1 or 2) */
|
||||
BYTE wflag; /* win[] flag (b0:dirty) */
|
||||
BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */
|
||||
WORD id; /* Volume mount ID */
|
||||
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
|
||||
WORD csize; /* Cluster size [sectors] */
|
||||
#if FF_MAX_SS != FF_MIN_SS
|
||||
WORD ssize; /* Sector size (512, 1024, 2048 or 4096) */
|
||||
#endif
|
||||
#if FF_USE_LFN
|
||||
WCHAR* lfnbuf; /* LFN working buffer */
|
||||
#endif
|
||||
#if FF_FS_EXFAT
|
||||
BYTE* dirbuf; /* Directory entry block scratchpad buffer for exFAT */
|
||||
#endif
|
||||
#if FF_FS_REENTRANT
|
||||
FF_SYNC_t sobj; /* Identifier of sync object */
|
||||
#endif
|
||||
#if !FF_FS_READONLY
|
||||
DWORD last_clst; /* Last allocated cluster */
|
||||
DWORD free_clst; /* Number of free clusters */
|
||||
#endif
|
||||
#if FF_FS_RPATH
|
||||
DWORD cdir; /* Current directory start cluster (0:root) */
|
||||
#if FF_FS_EXFAT
|
||||
DWORD cdc_scl; /* Containing directory start cluster (invalid when cdir is 0) */
|
||||
DWORD cdc_size; /* b31-b8:Size of containing directory, b7-b0: Chain status */
|
||||
DWORD cdc_ofs; /* Offset in the containing directory (invalid when cdir is 0) */
|
||||
#endif
|
||||
#endif
|
||||
DWORD n_fatent; /* Number of FAT entries (number of clusters + 2) */
|
||||
DWORD fsize; /* Size of an FAT [sectors] */
|
||||
DWORD volbase; /* Volume base sector */
|
||||
DWORD fatbase; /* FAT base sector */
|
||||
DWORD dirbase; /* Root directory base sector/cluster */
|
||||
DWORD database; /* Data base sector */
|
||||
DWORD winsect; /* Current sector appearing in the win[] */
|
||||
BYTE win[FF_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
|
||||
} FATFS;
|
||||
|
||||
|
||||
|
||||
/* Object ID and allocation information (FFOBJID) */
|
||||
|
||||
typedef struct {
|
||||
FATFS* fs; /* Pointer to the hosting volume of this object */
|
||||
WORD id; /* Hosting volume mount ID */
|
||||
BYTE attr; /* Object attribute */
|
||||
BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous, =3:flagmented in this session, b2:sub-directory stretched) */
|
||||
DWORD sclust; /* Object data start cluster (0:no cluster or root directory) */
|
||||
FSIZE_t objsize; /* Object size (valid when sclust != 0) */
|
||||
#if FF_FS_EXFAT
|
||||
DWORD n_cont; /* Size of first fragment - 1 (valid when stat == 3) */
|
||||
DWORD n_frag; /* Size of last fragment needs to be written to FAT (valid when not zero) */
|
||||
DWORD c_scl; /* Containing directory start cluster (valid when sclust != 0) */
|
||||
DWORD c_size; /* b31-b8:Size of containing directory, b7-b0: Chain status (valid when c_scl != 0) */
|
||||
DWORD c_ofs; /* Offset in the containing directory (valid when file object and sclust != 0) */
|
||||
#endif
|
||||
#if FF_FS_LOCK
|
||||
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
|
||||
#endif
|
||||
} FFOBJID;
|
||||
|
||||
|
||||
|
||||
/* File object structure (FIL) */
|
||||
|
||||
typedef struct {
|
||||
FFOBJID obj; /* Object identifier (must be the 1st member to detect invalid object pointer) */
|
||||
BYTE flag; /* File status flags */
|
||||
BYTE err; /* Abort flag (error code) */
|
||||
FSIZE_t fptr; /* File read/write pointer (Zeroed on file open) */
|
||||
DWORD clust; /* Current cluster of fpter (invalid when fptr is 0) */
|
||||
DWORD sect; /* Sector number appearing in buf[] (0:invalid) */
|
||||
#if !FF_FS_READONLY
|
||||
DWORD dir_sect; /* Sector number containing the directory entry (not used at exFAT) */
|
||||
BYTE* dir_ptr; /* Pointer to the directory entry in the win[] (not used at exFAT) */
|
||||
#endif
|
||||
#if FF_USE_FASTSEEK
|
||||
DWORD* cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */
|
||||
#endif
|
||||
#if !FF_FS_TINY
|
||||
BYTE buf[FF_MAX_SS]; /* File private data read/write window */
|
||||
#endif
|
||||
} FIL;
|
||||
|
||||
|
||||
|
||||
/* Directory object structure (FF_DIR) */
|
||||
|
||||
typedef struct {
|
||||
FFOBJID obj; /* Object identifier */
|
||||
DWORD dptr; /* Current read/write offset */
|
||||
DWORD clust; /* Current cluster */
|
||||
DWORD sect; /* Current sector (0:Read operation has terminated) */
|
||||
BYTE* dir; /* Pointer to the directory item in the win[] */
|
||||
BYTE fn[12]; /* SFN (in/out) {body[8],ext[3],status[1]} */
|
||||
#if FF_USE_LFN
|
||||
DWORD blk_ofs; /* Offset of current entry block being processed (0xFFFFFFFF:Invalid) */
|
||||
#endif
|
||||
#if FF_USE_FIND
|
||||
const TCHAR* pat; /* Pointer to the name matching pattern */
|
||||
#endif
|
||||
} FF_DIR;
|
||||
|
||||
|
||||
|
||||
/* File information structure (FILINFO) */
|
||||
|
||||
typedef struct {
|
||||
FSIZE_t fsize; /* File size */
|
||||
WORD fdate; /* Modified date */
|
||||
WORD ftime; /* Modified time */
|
||||
BYTE fattrib; /* File attribute */
|
||||
#if FF_USE_LFN
|
||||
TCHAR altname[FF_SFN_BUF + 1];/* Altenative file name */
|
||||
TCHAR fname[FF_LFN_BUF + 1]; /* Primary file name */
|
||||
#else
|
||||
TCHAR fname[12 + 1]; /* File name */
|
||||
#endif
|
||||
} FILINFO;
|
||||
|
||||
|
||||
|
||||
/* File function return code (FRESULT) */
|
||||
|
||||
typedef enum {
|
||||
FR_OK = 0, /* (0) Succeeded */
|
||||
FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */
|
||||
FR_INT_ERR, /* (2) Assertion failed */
|
||||
FR_NOT_READY, /* (3) The physical drive cannot work */
|
||||
FR_NO_FILE, /* (4) Could not find the file */
|
||||
FR_NO_PATH, /* (5) Could not find the path */
|
||||
FR_INVALID_NAME, /* (6) The path name format is invalid */
|
||||
FR_DENIED, /* (7) Access denied due to prohibited access or directory full */
|
||||
FR_EXIST, /* (8) Access denied due to prohibited access */
|
||||
FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
|
||||
FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
|
||||
FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
|
||||
FR_NOT_ENABLED, /* (12) The volume has no work area */
|
||||
FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */
|
||||
FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any problem */
|
||||
FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
|
||||
FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
|
||||
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
|
||||
FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > FF_FS_LOCK */
|
||||
FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
|
||||
} FRESULT;
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* FatFs module application interface */
|
||||
|
||||
FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */
|
||||
FRESULT f_close (FIL* fp); /* Close an open file object */
|
||||
FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from the file */
|
||||
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to the file */
|
||||
FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */
|
||||
FRESULT f_truncate (FIL* fp); /* Truncate the file */
|
||||
FRESULT f_sync (FIL* fp); /* Flush cached data of the writing file */
|
||||
FRESULT f_opendir (FF_DIR* dp, const TCHAR* path); /* Open a directory */
|
||||
FRESULT f_closedir (FF_DIR* dp); /* Close an open directory */
|
||||
FRESULT f_readdir (FF_DIR* dp, FILINFO* fno); /* Read a directory item */
|
||||
FRESULT f_findfirst (FF_DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern); /* Find first file */
|
||||
FRESULT f_findnext (FF_DIR* dp, FILINFO* fno); /* Find next file */
|
||||
FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */
|
||||
FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */
|
||||
FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */
|
||||
FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */
|
||||
FRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask); /* Change attribute of a file/dir */
|
||||
FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change timestamp of a file/dir */
|
||||
FRESULT f_chdir (const TCHAR* path); /* Change current directory */
|
||||
FRESULT f_chdrive (const TCHAR* path); /* Change current drive */
|
||||
FRESULT f_getcwd (TCHAR* buff, UINT len); /* Get current directory */
|
||||
FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */
|
||||
FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */
|
||||
FRESULT f_setlabel (const TCHAR* label); /* Set volume label */
|
||||
FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */
|
||||
FRESULT f_expand (FIL* fp, FSIZE_t szf, BYTE opt); /* Allocate a contiguous block to the file */
|
||||
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */
|
||||
FRESULT f_mkfs (const TCHAR* path, BYTE opt, DWORD au, void* work, UINT len); /* Create a FAT volume */
|
||||
FRESULT f_fdisk (BYTE pdrv, const DWORD* szt, void* work); /* Divide a physical drive into some partitions */
|
||||
FRESULT f_setcp (WORD cp); /* Set current code page */
|
||||
int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */
|
||||
int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */
|
||||
int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */
|
||||
TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */
|
||||
|
||||
#define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize))
|
||||
#define f_error(fp) ((fp)->err)
|
||||
#define f_tell(fp) ((fp)->fptr)
|
||||
#define f_size(fp) ((fp)->obj.objsize)
|
||||
#define f_rewind(fp) f_lseek((fp), 0)
|
||||
#define f_rewinddir(dp) f_readdir((dp), 0)
|
||||
#define f_rmdir(path) f_unlink(path)
|
||||
#define f_unmount(path) f_mount(0, path, 0)
|
||||
|
||||
#ifndef EOF
|
||||
#define EOF (-1)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Additional user defined functions */
|
||||
|
||||
/* RTC function */
|
||||
#if !FF_FS_READONLY && !FF_FS_NORTC
|
||||
DWORD get_fattime (void);
|
||||
#endif
|
||||
|
||||
/* LFN support functions */
|
||||
#if FF_USE_LFN >= 1 /* Code conversion (defined in unicode.c) */
|
||||
WCHAR ff_oem2uni (WCHAR oem, WORD cp); /* OEM code to Unicode conversion */
|
||||
WCHAR ff_uni2oem (DWORD uni, WORD cp); /* Unicode to OEM code conversion */
|
||||
DWORD ff_wtoupper (DWORD uni); /* Unicode upper-case conversion */
|
||||
#endif
|
||||
#if FF_USE_LFN == 3 /* Dynamic memory allocation */
|
||||
void* ff_memalloc (UINT msize); /* Allocate memory block */
|
||||
void ff_memfree (void* mblock); /* Free memory block */
|
||||
#endif
|
||||
|
||||
/* Sync functions */
|
||||
#if FF_FS_REENTRANT
|
||||
int ff_cre_syncobj (BYTE vol, FF_SYNC_t* sobj); /* Create a sync object */
|
||||
int ff_req_grant (FF_SYNC_t sobj); /* Lock sync object */
|
||||
void ff_rel_grant (FF_SYNC_t sobj); /* Unlock sync object */
|
||||
int ff_del_syncobj (FF_SYNC_t sobj); /* Delete a sync object */
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Flags and offset address */
|
||||
|
||||
|
||||
/* File access mode and open method flags (3rd argument of f_open) */
|
||||
#define FA_READ 0x01
|
||||
#define FA_WRITE 0x02
|
||||
#define FA_OPEN_EXISTING 0x00
|
||||
#define FA_CREATE_NEW 0x04
|
||||
#define FA_CREATE_ALWAYS 0x08
|
||||
#define FA_OPEN_ALWAYS 0x10
|
||||
#define FA_OPEN_APPEND 0x30
|
||||
|
||||
/* Fast seek controls (2nd argument of f_lseek) */
|
||||
#define CREATE_LINKMAP ((FSIZE_t)0 - 1)
|
||||
|
||||
/* Format options (2nd argument of f_mkfs) */
|
||||
#define FM_FAT 0x01
|
||||
#define FM_FAT32 0x02
|
||||
#define FM_EXFAT 0x04
|
||||
#define FM_ANY 0x07
|
||||
#define FM_SFD 0x08
|
||||
|
||||
/* Filesystem type (FATFS.fs_type) */
|
||||
#define FS_FAT12 1
|
||||
#define FS_FAT16 2
|
||||
#define FS_FAT32 3
|
||||
#define FS_EXFAT 4
|
||||
|
||||
/* File attribute bits for directory entry (FILINFO.fattrib) */
|
||||
#define AM_RDO 0x01 /* Read only */
|
||||
#define AM_HID 0x02 /* Hidden */
|
||||
#define AM_SYS 0x04 /* System */
|
||||
#define AM_DIR 0x10 /* Directory */
|
||||
#define AM_ARC 0x20 /* Archive */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FF_DEFINED */
|
||||
/*----------------------------------------------------------------------------/
|
||||
/ FatFs - Generic FAT Filesystem module R0.13a /
|
||||
/-----------------------------------------------------------------------------/
|
||||
/
|
||||
/ Copyright (C) 2017, ChaN, all right reserved.
|
||||
/
|
||||
/ FatFs module is an open source software. Redistribution and use of FatFs in
|
||||
/ source and binary forms, with or without modification, are permitted provided
|
||||
/ that the following condition is met:
|
||||
|
||||
/ 1. Redistributions of source code must retain the above copyright notice,
|
||||
/ this condition and the following disclaimer.
|
||||
/
|
||||
/ This software is provided by the copyright holder and contributors "AS IS"
|
||||
/ and any warranties related to this software are DISCLAIMED.
|
||||
/ The copyright owner or contributors be NOT LIABLE for any damages caused
|
||||
/ by use of this software.
|
||||
/
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifndef FF_DEFINED
|
||||
#define FF_DEFINED 89352 /* Revision ID */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "integer.h" /* Basic integer types */
|
||||
#include "ffconf.h" /* FatFs configuration options */
|
||||
|
||||
#if FF_DEFINED != FFCONF_DEF
|
||||
#error Wrong configuration file (ffconf.h).
|
||||
#endif
|
||||
|
||||
#ifdef FF_DEFINE_DIR
|
||||
#define FF_DIR DIR
|
||||
#endif
|
||||
|
||||
|
||||
/* Definitions of volume management */
|
||||
|
||||
#if FF_MULTI_PARTITION /* Multiple partition configuration */
|
||||
typedef struct {
|
||||
BYTE pd; /* Physical drive number */
|
||||
BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
|
||||
} PARTITION;
|
||||
extern PARTITION VolToPart[]; /* Volume - Partition resolution table */
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Type of path name strings on FatFs API */
|
||||
|
||||
#ifndef _INC_TCHAR
|
||||
#define _INC_TCHAR
|
||||
|
||||
#if FF_USE_LFN && FF_LFN_UNICODE == 1 /* Unicode in UTF-16 encoding */
|
||||
typedef WCHAR TCHAR;
|
||||
#define _T(x) L ## x
|
||||
#define _TEXT(x) L ## x
|
||||
#elif FF_USE_LFN && FF_LFN_UNICODE == 2 /* Unicode in UTF-8 encoding */
|
||||
typedef char TCHAR;
|
||||
#define _T(x) u8 ## x
|
||||
#define _TEXT(x) u8 ## x
|
||||
#elif FF_USE_LFN && (FF_LFN_UNICODE < 0 || FF_LFN_UNICODE > 2)
|
||||
#error Wrong FF_LFN_UNICODE setting
|
||||
#else /* ANSI/OEM code in SBCS/DBCS */
|
||||
typedef char TCHAR;
|
||||
#define _T(x) x
|
||||
#define _TEXT(x) x
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Type of file size variables */
|
||||
|
||||
#if FF_FS_EXFAT
|
||||
typedef QWORD FSIZE_t;
|
||||
#else
|
||||
typedef DWORD FSIZE_t;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Filesystem object structure (FATFS) */
|
||||
|
||||
typedef struct {
|
||||
BYTE fs_type; /* Filesystem type (0:N/A) */
|
||||
BYTE pdrv; /* Physical drive number */
|
||||
BYTE n_fats; /* Number of FATs (1 or 2) */
|
||||
BYTE wflag; /* win[] flag (b0:dirty) */
|
||||
BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */
|
||||
WORD id; /* Volume mount ID */
|
||||
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
|
||||
WORD csize; /* Cluster size [sectors] */
|
||||
#if FF_MAX_SS != FF_MIN_SS
|
||||
WORD ssize; /* Sector size (512, 1024, 2048 or 4096) */
|
||||
#endif
|
||||
#if FF_USE_LFN
|
||||
WCHAR* lfnbuf; /* LFN working buffer */
|
||||
#endif
|
||||
#if FF_FS_EXFAT
|
||||
BYTE* dirbuf; /* Directory entry block scratchpad buffer for exFAT */
|
||||
#endif
|
||||
#if FF_FS_REENTRANT
|
||||
FF_SYNC_t sobj; /* Identifier of sync object */
|
||||
#endif
|
||||
#if !FF_FS_READONLY
|
||||
DWORD last_clst; /* Last allocated cluster */
|
||||
DWORD free_clst; /* Number of free clusters */
|
||||
#endif
|
||||
#if FF_FS_RPATH
|
||||
DWORD cdir; /* Current directory start cluster (0:root) */
|
||||
#if FF_FS_EXFAT
|
||||
DWORD cdc_scl; /* Containing directory start cluster (invalid when cdir is 0) */
|
||||
DWORD cdc_size; /* b31-b8:Size of containing directory, b7-b0: Chain status */
|
||||
DWORD cdc_ofs; /* Offset in the containing directory (invalid when cdir is 0) */
|
||||
#endif
|
||||
#endif
|
||||
DWORD n_fatent; /* Number of FAT entries (number of clusters + 2) */
|
||||
DWORD fsize; /* Size of an FAT [sectors] */
|
||||
DWORD volbase; /* Volume base sector */
|
||||
DWORD fatbase; /* FAT base sector */
|
||||
DWORD dirbase; /* Root directory base sector/cluster */
|
||||
DWORD database; /* Data base sector */
|
||||
DWORD winsect; /* Current sector appearing in the win[] */
|
||||
BYTE win[FF_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
|
||||
} FATFS;
|
||||
|
||||
|
||||
|
||||
/* Object ID and allocation information (FFOBJID) */
|
||||
|
||||
typedef struct {
|
||||
FATFS* fs; /* Pointer to the hosting volume of this object */
|
||||
WORD id; /* Hosting volume mount ID */
|
||||
BYTE attr; /* Object attribute */
|
||||
BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous, =3:flagmented in this session, b2:sub-directory stretched) */
|
||||
DWORD sclust; /* Object data start cluster (0:no cluster or root directory) */
|
||||
FSIZE_t objsize; /* Object size (valid when sclust != 0) */
|
||||
#if FF_FS_EXFAT
|
||||
DWORD n_cont; /* Size of first fragment - 1 (valid when stat == 3) */
|
||||
DWORD n_frag; /* Size of last fragment needs to be written to FAT (valid when not zero) */
|
||||
DWORD c_scl; /* Containing directory start cluster (valid when sclust != 0) */
|
||||
DWORD c_size; /* b31-b8:Size of containing directory, b7-b0: Chain status (valid when c_scl != 0) */
|
||||
DWORD c_ofs; /* Offset in the containing directory (valid when file object and sclust != 0) */
|
||||
#endif
|
||||
#if FF_FS_LOCK
|
||||
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
|
||||
#endif
|
||||
} FFOBJID;
|
||||
|
||||
|
||||
|
||||
/* File object structure (FIL) */
|
||||
|
||||
typedef struct {
|
||||
FFOBJID obj; /* Object identifier (must be the 1st member to detect invalid object pointer) */
|
||||
BYTE flag; /* File status flags */
|
||||
BYTE err; /* Abort flag (error code) */
|
||||
FSIZE_t fptr; /* File read/write pointer (Zeroed on file open) */
|
||||
DWORD clust; /* Current cluster of fpter (invalid when fptr is 0) */
|
||||
DWORD sect; /* Sector number appearing in buf[] (0:invalid) */
|
||||
#if !FF_FS_READONLY
|
||||
DWORD dir_sect; /* Sector number containing the directory entry (not used at exFAT) */
|
||||
BYTE* dir_ptr; /* Pointer to the directory entry in the win[] (not used at exFAT) */
|
||||
#endif
|
||||
#if FF_USE_FASTSEEK
|
||||
DWORD* cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */
|
||||
#endif
|
||||
#if !FF_FS_TINY
|
||||
BYTE buf[FF_MAX_SS]; /* File private data read/write window */
|
||||
#endif
|
||||
} FIL;
|
||||
|
||||
|
||||
|
||||
/* Directory object structure (FF_DIR) */
|
||||
|
||||
typedef struct {
|
||||
FFOBJID obj; /* Object identifier */
|
||||
DWORD dptr; /* Current read/write offset */
|
||||
DWORD clust; /* Current cluster */
|
||||
DWORD sect; /* Current sector (0:Read operation has terminated) */
|
||||
BYTE* dir; /* Pointer to the directory item in the win[] */
|
||||
BYTE fn[12]; /* SFN (in/out) {body[8],ext[3],status[1]} */
|
||||
#if FF_USE_LFN
|
||||
DWORD blk_ofs; /* Offset of current entry block being processed (0xFFFFFFFF:Invalid) */
|
||||
#endif
|
||||
#if FF_USE_FIND
|
||||
const TCHAR* pat; /* Pointer to the name matching pattern */
|
||||
#endif
|
||||
} FF_DIR;
|
||||
|
||||
|
||||
|
||||
/* File information structure (FILINFO) */
|
||||
|
||||
typedef struct {
|
||||
FSIZE_t fsize; /* File size */
|
||||
WORD fdate; /* Modified date */
|
||||
WORD ftime; /* Modified time */
|
||||
BYTE fattrib; /* File attribute */
|
||||
#if FF_USE_LFN
|
||||
TCHAR altname[FF_SFN_BUF + 1];/* Altenative file name */
|
||||
TCHAR fname[FF_LFN_BUF + 1]; /* Primary file name */
|
||||
#else
|
||||
TCHAR fname[12 + 1]; /* File name */
|
||||
#endif
|
||||
} FILINFO;
|
||||
|
||||
|
||||
|
||||
/* File function return code (FRESULT) */
|
||||
|
||||
typedef enum {
|
||||
FR_OK = 0, /* (0) Succeeded */
|
||||
FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */
|
||||
FR_INT_ERR, /* (2) Assertion failed */
|
||||
FR_NOT_READY, /* (3) The physical drive cannot work */
|
||||
FR_NO_FILE, /* (4) Could not find the file */
|
||||
FR_NO_PATH, /* (5) Could not find the path */
|
||||
FR_INVALID_NAME, /* (6) The path name format is invalid */
|
||||
FR_DENIED, /* (7) Access denied due to prohibited access or directory full */
|
||||
FR_EXIST, /* (8) Access denied due to prohibited access */
|
||||
FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
|
||||
FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
|
||||
FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
|
||||
FR_NOT_ENABLED, /* (12) The volume has no work area */
|
||||
FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */
|
||||
FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any problem */
|
||||
FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
|
||||
FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
|
||||
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
|
||||
FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > FF_FS_LOCK */
|
||||
FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
|
||||
} FRESULT;
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* FatFs module application interface */
|
||||
|
||||
FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */
|
||||
FRESULT f_close (FIL* fp); /* Close an open file object */
|
||||
FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from the file */
|
||||
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to the file */
|
||||
FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */
|
||||
FRESULT f_truncate (FIL* fp); /* Truncate the file */
|
||||
FRESULT f_sync (FIL* fp); /* Flush cached data of the writing file */
|
||||
FRESULT f_opendir (FF_DIR* dp, const TCHAR* path); /* Open a directory */
|
||||
FRESULT f_closedir (FF_DIR* dp); /* Close an open directory */
|
||||
FRESULT f_readdir (FF_DIR* dp, FILINFO* fno); /* Read a directory item */
|
||||
FRESULT f_findfirst (FF_DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern); /* Find first file */
|
||||
FRESULT f_findnext (FF_DIR* dp, FILINFO* fno); /* Find next file */
|
||||
FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */
|
||||
FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */
|
||||
FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */
|
||||
FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */
|
||||
FRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask); /* Change attribute of a file/dir */
|
||||
FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change timestamp of a file/dir */
|
||||
FRESULT f_chdir (const TCHAR* path); /* Change current directory */
|
||||
FRESULT f_chdrive (const TCHAR* path); /* Change current drive */
|
||||
FRESULT f_getcwd (TCHAR* buff, UINT len); /* Get current directory */
|
||||
FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */
|
||||
FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */
|
||||
FRESULT f_setlabel (const TCHAR* label); /* Set volume label */
|
||||
FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */
|
||||
FRESULT f_expand (FIL* fp, FSIZE_t szf, BYTE opt); /* Allocate a contiguous block to the file */
|
||||
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */
|
||||
FRESULT f_mkfs (const TCHAR* path, BYTE opt, DWORD au, void* work, UINT len); /* Create a FAT volume */
|
||||
FRESULT f_fdisk (BYTE pdrv, const DWORD* szt, void* work); /* Divide a physical drive into some partitions */
|
||||
FRESULT f_setcp (WORD cp); /* Set current code page */
|
||||
int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */
|
||||
int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */
|
||||
int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */
|
||||
TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */
|
||||
|
||||
#define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize))
|
||||
#define f_error(fp) ((fp)->err)
|
||||
#define f_tell(fp) ((fp)->fptr)
|
||||
#define f_size(fp) ((fp)->obj.objsize)
|
||||
#define f_rewind(fp) f_lseek((fp), 0)
|
||||
#define f_rewinddir(dp) f_readdir((dp), 0)
|
||||
#define f_rmdir(path) f_unlink(path)
|
||||
#define f_unmount(path) f_mount(0, path, 0)
|
||||
|
||||
#ifndef EOF
|
||||
#define EOF (-1)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Additional user defined functions */
|
||||
|
||||
/* RTC function */
|
||||
#if !FF_FS_READONLY && !FF_FS_NORTC
|
||||
DWORD get_fattime (void);
|
||||
#endif
|
||||
|
||||
/* LFN support functions */
|
||||
#if FF_USE_LFN >= 1 /* Code conversion (defined in unicode.c) */
|
||||
WCHAR ff_oem2uni (WCHAR oem, WORD cp); /* OEM code to Unicode conversion */
|
||||
WCHAR ff_uni2oem (DWORD uni, WORD cp); /* Unicode to OEM code conversion */
|
||||
DWORD ff_wtoupper (DWORD uni); /* Unicode upper-case conversion */
|
||||
#endif
|
||||
#if FF_USE_LFN == 3 /* Dynamic memory allocation */
|
||||
void* ff_memalloc (UINT msize); /* Allocate memory block */
|
||||
void ff_memfree (void* mblock); /* Free memory block */
|
||||
#endif
|
||||
|
||||
/* Sync functions */
|
||||
#if FF_FS_REENTRANT
|
||||
int ff_cre_syncobj (BYTE vol, FF_SYNC_t* sobj); /* Create a sync object */
|
||||
int ff_req_grant (FF_SYNC_t sobj); /* Lock sync object */
|
||||
void ff_rel_grant (FF_SYNC_t sobj); /* Unlock sync object */
|
||||
int ff_del_syncobj (FF_SYNC_t sobj); /* Delete a sync object */
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Flags and offset address */
|
||||
|
||||
|
||||
/* File access mode and open method flags (3rd argument of f_open) */
|
||||
#define FA_READ 0x01
|
||||
#define FA_WRITE 0x02
|
||||
#define FA_OPEN_EXISTING 0x00
|
||||
#define FA_CREATE_NEW 0x04
|
||||
#define FA_CREATE_ALWAYS 0x08
|
||||
#define FA_OPEN_ALWAYS 0x10
|
||||
#define FA_OPEN_APPEND 0x30
|
||||
|
||||
/* Fast seek controls (2nd argument of f_lseek) */
|
||||
#define CREATE_LINKMAP ((FSIZE_t)0 - 1)
|
||||
|
||||
/* Format options (2nd argument of f_mkfs) */
|
||||
#define FM_FAT 0x01
|
||||
#define FM_FAT32 0x02
|
||||
#define FM_EXFAT 0x04
|
||||
#define FM_ANY 0x07
|
||||
#define FM_SFD 0x08
|
||||
|
||||
/* Filesystem type (FATFS.fs_type) */
|
||||
#define FS_FAT12 1
|
||||
#define FS_FAT16 2
|
||||
#define FS_FAT32 3
|
||||
#define FS_EXFAT 4
|
||||
|
||||
/* File attribute bits for directory entry (FILINFO.fattrib) */
|
||||
#define AM_RDO 0x01 /* Read only */
|
||||
#define AM_HID 0x02 /* Hidden */
|
||||
#define AM_SYS 0x04 /* System */
|
||||
#define AM_DIR 0x10 /* Directory */
|
||||
#define AM_ARC 0x20 /* Archive */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FF_DEFINED */
|
||||
|
@ -1,304 +1,304 @@
|
||||
#include <sys/param.h>
|
||||
#include "sdkconfig.h"
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs - Configuration file
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FFCONF_DEF 89352 /* Revision ID */
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Function Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_FS_READONLY 0
|
||||
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
|
||||
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
|
||||
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
|
||||
/ and optional writing functions as well. */
|
||||
|
||||
|
||||
#define FF_FS_MINIMIZE 0
|
||||
/* This option defines minimization level to remove some basic API functions.
|
||||
/
|
||||
/ 0: Basic functions are fully enabled.
|
||||
/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename()
|
||||
/ are removed.
|
||||
/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
|
||||
/ 3: f_lseek() function is removed in addition to 2. */
|
||||
|
||||
|
||||
#define FF_USE_STRFUNC 0
|
||||
/* This option switches string functions, f_gets(), f_putc(), f_puts() and f_printf().
|
||||
/
|
||||
/ 0: Disable string functions.
|
||||
/ 1: Enable without LF-CRLF conversion.
|
||||
/ 2: Enable with LF-CRLF conversion. */
|
||||
|
||||
|
||||
#define FF_USE_FIND 0
|
||||
/* This option switches filtered directory read functions, f_findfirst() and
|
||||
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
|
||||
|
||||
|
||||
#define FF_USE_MKFS 1
|
||||
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_FASTSEEK 0
|
||||
/* This option switches fast seek function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_EXPAND 0
|
||||
/* This option switches f_expand function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_CHMOD 0
|
||||
/* This option switches attribute manipulation functions, f_chmod() and f_utime().
|
||||
/ (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */
|
||||
|
||||
|
||||
#define FF_USE_LABEL 0
|
||||
/* This option switches volume label functions, f_getlabel() and f_setlabel().
|
||||
/ (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_FORWARD 0
|
||||
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Locale and Namespace Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_CODE_PAGE CONFIG_FATFS_CODEPAGE
|
||||
/* This option specifies the OEM code page to be used on the target system.
|
||||
/ Incorrect code page setting can cause a file open failure.
|
||||
/
|
||||
/ 437 - U.S.
|
||||
/ 720 - Arabic
|
||||
/ 737 - Greek
|
||||
/ 771 - KBL
|
||||
/ 775 - Baltic
|
||||
/ 850 - Latin 1
|
||||
/ 852 - Latin 2
|
||||
/ 855 - Cyrillic
|
||||
/ 857 - Turkish
|
||||
/ 860 - Portuguese
|
||||
/ 861 - Icelandic
|
||||
/ 862 - Hebrew
|
||||
/ 863 - Canadian French
|
||||
/ 864 - Arabic
|
||||
/ 865 - Nordic
|
||||
/ 866 - Russian
|
||||
/ 869 - Greek 2
|
||||
/ 932 - Japanese (DBCS)
|
||||
/ 936 - Simplified Chinese (DBCS)
|
||||
/ 949 - Korean (DBCS)
|
||||
/ 950 - Traditional Chinese (DBCS)
|
||||
/ 0 - Include all code pages above and configured by f_setcp()
|
||||
*/
|
||||
|
||||
|
||||
#if defined(CONFIG_FATFS_LFN_STACK)
|
||||
#define FF_USE_LFN 2
|
||||
#elif defined(CONFIG_FATFS_LFN_HEAP)
|
||||
#define FF_USE_LFN 3
|
||||
#else /* CONFIG_FATFS_LFN_NONE */
|
||||
#define FF_USE_LFN 0
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FATFS_MAX_LFN
|
||||
#define FF_MAX_LFN CONFIG_FATFS_MAX_LFN
|
||||
#endif
|
||||
|
||||
/* The FF_USE_LFN switches the support for LFN (long file name).
|
||||
/
|
||||
/ 0: Disable LFN. FF_MAX_LFN has no effect.
|
||||
/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
|
||||
/ 2: Enable LFN with dynamic working buffer on the STACK.
|
||||
/ 3: Enable LFN with dynamic working buffer on the HEAP.
|
||||
/
|
||||
/ To enable the LFN, ffunicode.c needs to be added to the project. The LFN function
|
||||
/ requiers certain internal working buffer occupies (FF_MAX_LFN + 1) * 2 bytes and
|
||||
/ additional (FF_MAX_LFN + 44) / 15 * 32 bytes when exFAT is enabled.
|
||||
/ The FF_MAX_LFN defines size of the working buffer in UTF-16 code unit and it can
|
||||
/ be in range of 12 to 255. It is recommended to be set 255 to fully support LFN
|
||||
/ specification.
|
||||
/ When use stack for the working buffer, take care on stack overflow. When use heap
|
||||
/ memory for the working buffer, memory management functions, ff_memalloc() and
|
||||
/ ff_memfree() in ffsystem.c, need to be added to the project. */
|
||||
|
||||
|
||||
#ifdef CONFIG_FATFS_API_ENCODING_UTF_8
|
||||
#define FF_LFN_UNICODE 2
|
||||
#elif defined(CONFIG_FATFS_API_ENCODING_UTF_16)
|
||||
#define FF_LFN_UNICODE 1
|
||||
#else /* CONFIG_FATFS_API_ENCODING_ANSI_OEM */
|
||||
#define FF_LFN_UNICODE 0
|
||||
#endif
|
||||
/* This option switches the character encoding on the API when LFN is enabled.
|
||||
/
|
||||
/ 0: ANSI/OEM in current CP (TCHAR = char)
|
||||
/ 1: Unicode in UTF-16 (TCHAR = WCHAR)
|
||||
/ 2: Unicode in UTF-8 (TCHAR = char)
|
||||
/
|
||||
/ Also behavior of string I/O functions will be affected by this option.
|
||||
/ When LFN is not enabled, this option has no effect. */
|
||||
|
||||
|
||||
#define FF_LFN_BUF 255
|
||||
#define FF_SFN_BUF 12
|
||||
/* This set of options defines size of file name members in the FILINFO structure
|
||||
/ which is used to read out directory items. These values should be suffcient for
|
||||
/ the file names to read. The maximum possible length of the read file name depends
|
||||
/ on character encoding. When LFN is not enabled, these options have no effect. */
|
||||
|
||||
|
||||
#define FF_STRF_ENCODE 3
|
||||
/* When FF_LFN_UNICODE >= 1 with LFN enabled, string I/O functions, f_gets(),
|
||||
/ f_putc(), f_puts and f_printf() convert the character encoding in it.
|
||||
/ This option selects assumption of character encoding ON THE FILE to be
|
||||
/ read/written via those functions.
|
||||
/
|
||||
/ 0: ANSI/OEM in current CP
|
||||
/ 1: Unicode in UTF-16LE
|
||||
/ 2: Unicode in UTF-16BE
|
||||
/ 3: Unicode in UTF-8
|
||||
*/
|
||||
|
||||
|
||||
#define FF_FS_RPATH 0
|
||||
/* This option configures support for relative path.
|
||||
/
|
||||
/ 0: Disable relative path and remove related functions.
|
||||
/ 1: Enable relative path. f_chdir() and f_chdrive() are available.
|
||||
/ 2: f_getcwd() function is available in addition to 1.
|
||||
*/
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Drive/Volume Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_VOLUMES 2
|
||||
/* Number of volumes (logical drives) to be used. (1-10) */
|
||||
|
||||
|
||||
#define FF_STR_VOLUME_ID 0
|
||||
#define FF_VOLUME_STRS "RAM","NAND","CF","SD","SD2","USB","USB2","USB3"
|
||||
/* FF_STR_VOLUME_ID switches string support for volume ID.
|
||||
/ When FF_STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive
|
||||
/ number in the path name. FF_VOLUME_STRS defines the drive ID strings for each
|
||||
/ logical drives. Number of items must be equal to FF_VOLUMES. Valid characters for
|
||||
/ the drive ID strings are: A-Z and 0-9. */
|
||||
|
||||
|
||||
#define FF_MULTI_PARTITION 1
|
||||
/* This option switches support for multiple volumes on the physical drive.
|
||||
/ By default (0), each logical drive number is bound to the same physical drive
|
||||
/ number and only an FAT volume found on the physical drive will be mounted.
|
||||
/ When this function is enabled (1), each logical drive number can be bound to
|
||||
/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
|
||||
/ funciton will be available. */
|
||||
|
||||
/* SD card sector size */
|
||||
#define FF_SS_SDCARD 512
|
||||
/* wear_levelling library sector size */
|
||||
#define FF_SS_WL CONFIG_WL_SECTOR_SIZE
|
||||
|
||||
#define FF_MIN_SS MIN(FF_SS_SDCARD, FF_SS_WL)
|
||||
#define FF_MAX_SS MAX(FF_SS_SDCARD, FF_SS_WL)
|
||||
/* This set of options configures the range of sector size to be supported. (512,
|
||||
/ 1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and
|
||||
/ harddisk. But a larger value may be required for on-board flash memory and some
|
||||
/ type of optical media. When FF_MAX_SS is larger than FF_MIN_SS, FatFs is configured
|
||||
/ for variable sector size mode and disk_ioctl() function needs to implement
|
||||
/ GET_SECTOR_SIZE command. */
|
||||
|
||||
|
||||
#define FF_USE_TRIM 0
|
||||
/* This option switches support for ATA-TRIM. (0:Disable or 1:Enable)
|
||||
/ To enable Trim function, also CTRL_TRIM command should be implemented to the
|
||||
/ disk_ioctl() function. */
|
||||
|
||||
|
||||
#define FF_FS_NOFSINFO 0
|
||||
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
|
||||
/ option, and f_getfree() function at first time after volume mount will force
|
||||
/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
|
||||
/
|
||||
/ bit0=0: Use free cluster count in the FSINFO if available.
|
||||
/ bit0=1: Do not trust free cluster count in the FSINFO.
|
||||
/ bit1=0: Use last allocated cluster number in the FSINFO if available.
|
||||
/ bit1=1: Do not trust last allocated cluster number in the FSINFO.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ System Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_FS_TINY (!CONFIG_FATFS_PER_FILE_CACHE)
|
||||
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
|
||||
/ At the tiny configuration, size of file object (FIL) is shrinked FF_MAX_SS bytes.
|
||||
/ Instead of private sector buffer eliminated from the file object, common sector
|
||||
/ buffer in the filesystem object (FATFS) is used for the file data transfer. */
|
||||
|
||||
|
||||
#define FF_FS_EXFAT 0
|
||||
/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable)
|
||||
/ When enable exFAT, also LFN needs to be enabled.
|
||||
/ Note that enabling exFAT discards ANSI C (C89) compatibility. */
|
||||
|
||||
|
||||
#define FF_FS_NORTC 0
|
||||
#define FF_NORTC_MON 1
|
||||
#define FF_NORTC_MDAY 1
|
||||
#define FF_NORTC_YEAR 2017
|
||||
/* The option FF_FS_NORTC switches timestamp functiton. If the system does not have
|
||||
/ any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable
|
||||
/ the timestamp function. All objects modified by FatFs will have a fixed timestamp
|
||||
/ defined by FF_NORTC_MON, FF_NORTC_MDAY and FF_NORTC_YEAR in local time.
|
||||
/ To enable timestamp function (FF_FS_NORTC = 0), get_fattime() function need to be
|
||||
/ added to the project to read current time form real-time clock. FF_NORTC_MON,
|
||||
/ FF_NORTC_MDAY and FF_NORTC_YEAR have no effect.
|
||||
/ These options have no effect at read-only configuration (FF_FS_READONLY = 1). */
|
||||
|
||||
|
||||
#define FF_FS_LOCK CONFIG_FATFS_FS_LOCK
|
||||
/* The option FF_FS_LOCK switches file lock function to control duplicated file open
|
||||
/ and illegal operation to open objects. This option must be 0 when FF_FS_READONLY
|
||||
/ is 1.
|
||||
/
|
||||
/ 0: Disable file lock function. To avoid volume corruption, application program
|
||||
/ should avoid illegal open, remove and rename to the open objects.
|
||||
/ >0: Enable file lock function. The value defines how many files/sub-directories
|
||||
/ can be opened simultaneously under file lock control. Note that the file
|
||||
/ lock control is independent of re-entrancy. */
|
||||
|
||||
|
||||
#define FF_FS_REENTRANT 1
|
||||
#define FF_FS_TIMEOUT (CONFIG_FATFS_TIMEOUT_MS / portTICK_PERIOD_MS)
|
||||
#define FF_SYNC_t SemaphoreHandle_t
|
||||
/* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs
|
||||
/ module itself. Note that regardless of this option, file access to different
|
||||
/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
|
||||
/ and f_fdisk() function, are always not re-entrant. Only file/directory access
|
||||
/ to the same volume is under control of this function.
|
||||
/
|
||||
/ 0: Disable re-entrancy. FF_FS_TIMEOUT and FF_SYNC_t have no effect.
|
||||
/ 1: Enable re-entrancy. Also user provided synchronization handlers,
|
||||
/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
|
||||
/ function, must be added to the project. Samples are available in
|
||||
/ option/syscall.c.
|
||||
/
|
||||
/ The FF_FS_TIMEOUT defines timeout period in unit of time tick.
|
||||
/ The FF_SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
|
||||
/ SemaphoreHandle_t and etc. A header file for O/S definitions needs to be
|
||||
/ included somewhere in the scope of ff.h. */
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
|
||||
/*--- End of configuration options ---*/
|
||||
#include <sys/param.h>
|
||||
#include "sdkconfig.h"
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs - Configuration file
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FFCONF_DEF 89352 /* Revision ID */
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Function Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_FS_READONLY 0
|
||||
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
|
||||
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
|
||||
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
|
||||
/ and optional writing functions as well. */
|
||||
|
||||
|
||||
#define FF_FS_MINIMIZE 0
|
||||
/* This option defines minimization level to remove some basic API functions.
|
||||
/
|
||||
/ 0: Basic functions are fully enabled.
|
||||
/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename()
|
||||
/ are removed.
|
||||
/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
|
||||
/ 3: f_lseek() function is removed in addition to 2. */
|
||||
|
||||
|
||||
#define FF_USE_STRFUNC 0
|
||||
/* This option switches string functions, f_gets(), f_putc(), f_puts() and f_printf().
|
||||
/
|
||||
/ 0: Disable string functions.
|
||||
/ 1: Enable without LF-CRLF conversion.
|
||||
/ 2: Enable with LF-CRLF conversion. */
|
||||
|
||||
|
||||
#define FF_USE_FIND 0
|
||||
/* This option switches filtered directory read functions, f_findfirst() and
|
||||
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
|
||||
|
||||
|
||||
#define FF_USE_MKFS 1
|
||||
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_FASTSEEK 0
|
||||
/* This option switches fast seek function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_EXPAND 0
|
||||
/* This option switches f_expand function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_CHMOD 0
|
||||
/* This option switches attribute manipulation functions, f_chmod() and f_utime().
|
||||
/ (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */
|
||||
|
||||
|
||||
#define FF_USE_LABEL 0
|
||||
/* This option switches volume label functions, f_getlabel() and f_setlabel().
|
||||
/ (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_FORWARD 0
|
||||
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Locale and Namespace Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_CODE_PAGE CONFIG_FATFS_CODEPAGE
|
||||
/* This option specifies the OEM code page to be used on the target system.
|
||||
/ Incorrect code page setting can cause a file open failure.
|
||||
/
|
||||
/ 437 - U.S.
|
||||
/ 720 - Arabic
|
||||
/ 737 - Greek
|
||||
/ 771 - KBL
|
||||
/ 775 - Baltic
|
||||
/ 850 - Latin 1
|
||||
/ 852 - Latin 2
|
||||
/ 855 - Cyrillic
|
||||
/ 857 - Turkish
|
||||
/ 860 - Portuguese
|
||||
/ 861 - Icelandic
|
||||
/ 862 - Hebrew
|
||||
/ 863 - Canadian French
|
||||
/ 864 - Arabic
|
||||
/ 865 - Nordic
|
||||
/ 866 - Russian
|
||||
/ 869 - Greek 2
|
||||
/ 932 - Japanese (DBCS)
|
||||
/ 936 - Simplified Chinese (DBCS)
|
||||
/ 949 - Korean (DBCS)
|
||||
/ 950 - Traditional Chinese (DBCS)
|
||||
/ 0 - Include all code pages above and configured by f_setcp()
|
||||
*/
|
||||
|
||||
|
||||
#if defined(CONFIG_FATFS_LFN_STACK)
|
||||
#define FF_USE_LFN 2
|
||||
#elif defined(CONFIG_FATFS_LFN_HEAP)
|
||||
#define FF_USE_LFN 3
|
||||
#else /* CONFIG_FATFS_LFN_NONE */
|
||||
#define FF_USE_LFN 0
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FATFS_MAX_LFN
|
||||
#define FF_MAX_LFN CONFIG_FATFS_MAX_LFN
|
||||
#endif
|
||||
|
||||
/* The FF_USE_LFN switches the support for LFN (long file name).
|
||||
/
|
||||
/ 0: Disable LFN. FF_MAX_LFN has no effect.
|
||||
/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
|
||||
/ 2: Enable LFN with dynamic working buffer on the STACK.
|
||||
/ 3: Enable LFN with dynamic working buffer on the HEAP.
|
||||
/
|
||||
/ To enable the LFN, ffunicode.c needs to be added to the project. The LFN function
|
||||
/ requiers certain internal working buffer occupies (FF_MAX_LFN + 1) * 2 bytes and
|
||||
/ additional (FF_MAX_LFN + 44) / 15 * 32 bytes when exFAT is enabled.
|
||||
/ The FF_MAX_LFN defines size of the working buffer in UTF-16 code unit and it can
|
||||
/ be in range of 12 to 255. It is recommended to be set 255 to fully support LFN
|
||||
/ specification.
|
||||
/ When use stack for the working buffer, take care on stack overflow. When use heap
|
||||
/ memory for the working buffer, memory management functions, ff_memalloc() and
|
||||
/ ff_memfree() in ffsystem.c, need to be added to the project. */
|
||||
|
||||
|
||||
#ifdef CONFIG_FATFS_API_ENCODING_UTF_8
|
||||
#define FF_LFN_UNICODE 2
|
||||
#elif defined(CONFIG_FATFS_API_ENCODING_UTF_16)
|
||||
#define FF_LFN_UNICODE 1
|
||||
#else /* CONFIG_FATFS_API_ENCODING_ANSI_OEM */
|
||||
#define FF_LFN_UNICODE 0
|
||||
#endif
|
||||
/* This option switches the character encoding on the API when LFN is enabled.
|
||||
/
|
||||
/ 0: ANSI/OEM in current CP (TCHAR = char)
|
||||
/ 1: Unicode in UTF-16 (TCHAR = WCHAR)
|
||||
/ 2: Unicode in UTF-8 (TCHAR = char)
|
||||
/
|
||||
/ Also behavior of string I/O functions will be affected by this option.
|
||||
/ When LFN is not enabled, this option has no effect. */
|
||||
|
||||
|
||||
#define FF_LFN_BUF 255
|
||||
#define FF_SFN_BUF 12
|
||||
/* This set of options defines size of file name members in the FILINFO structure
|
||||
/ which is used to read out directory items. These values should be suffcient for
|
||||
/ the file names to read. The maximum possible length of the read file name depends
|
||||
/ on character encoding. When LFN is not enabled, these options have no effect. */
|
||||
|
||||
|
||||
#define FF_STRF_ENCODE 3
|
||||
/* When FF_LFN_UNICODE >= 1 with LFN enabled, string I/O functions, f_gets(),
|
||||
/ f_putc(), f_puts and f_printf() convert the character encoding in it.
|
||||
/ This option selects assumption of character encoding ON THE FILE to be
|
||||
/ read/written via those functions.
|
||||
/
|
||||
/ 0: ANSI/OEM in current CP
|
||||
/ 1: Unicode in UTF-16LE
|
||||
/ 2: Unicode in UTF-16BE
|
||||
/ 3: Unicode in UTF-8
|
||||
*/
|
||||
|
||||
|
||||
#define FF_FS_RPATH 0
|
||||
/* This option configures support for relative path.
|
||||
/
|
||||
/ 0: Disable relative path and remove related functions.
|
||||
/ 1: Enable relative path. f_chdir() and f_chdrive() are available.
|
||||
/ 2: f_getcwd() function is available in addition to 1.
|
||||
*/
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Drive/Volume Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_VOLUMES 2
|
||||
/* Number of volumes (logical drives) to be used. (1-10) */
|
||||
|
||||
|
||||
#define FF_STR_VOLUME_ID 0
|
||||
#define FF_VOLUME_STRS "RAM","NAND","CF","SD","SD2","USB","USB2","USB3"
|
||||
/* FF_STR_VOLUME_ID switches string support for volume ID.
|
||||
/ When FF_STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive
|
||||
/ number in the path name. FF_VOLUME_STRS defines the drive ID strings for each
|
||||
/ logical drives. Number of items must be equal to FF_VOLUMES. Valid characters for
|
||||
/ the drive ID strings are: A-Z and 0-9. */
|
||||
|
||||
|
||||
#define FF_MULTI_PARTITION 1
|
||||
/* This option switches support for multiple volumes on the physical drive.
|
||||
/ By default (0), each logical drive number is bound to the same physical drive
|
||||
/ number and only an FAT volume found on the physical drive will be mounted.
|
||||
/ When this function is enabled (1), each logical drive number can be bound to
|
||||
/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
|
||||
/ funciton will be available. */
|
||||
|
||||
/* SD card sector size */
|
||||
#define FF_SS_SDCARD 512
|
||||
/* wear_levelling library sector size */
|
||||
#define FF_SS_WL CONFIG_WL_SECTOR_SIZE
|
||||
|
||||
#define FF_MIN_SS MIN(FF_SS_SDCARD, FF_SS_WL)
|
||||
#define FF_MAX_SS MAX(FF_SS_SDCARD, FF_SS_WL)
|
||||
/* This set of options configures the range of sector size to be supported. (512,
|
||||
/ 1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and
|
||||
/ harddisk. But a larger value may be required for on-board flash memory and some
|
||||
/ type of optical media. When FF_MAX_SS is larger than FF_MIN_SS, FatFs is configured
|
||||
/ for variable sector size mode and disk_ioctl() function needs to implement
|
||||
/ GET_SECTOR_SIZE command. */
|
||||
|
||||
|
||||
#define FF_USE_TRIM 0
|
||||
/* This option switches support for ATA-TRIM. (0:Disable or 1:Enable)
|
||||
/ To enable Trim function, also CTRL_TRIM command should be implemented to the
|
||||
/ disk_ioctl() function. */
|
||||
|
||||
|
||||
#define FF_FS_NOFSINFO 0
|
||||
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
|
||||
/ option, and f_getfree() function at first time after volume mount will force
|
||||
/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
|
||||
/
|
||||
/ bit0=0: Use free cluster count in the FSINFO if available.
|
||||
/ bit0=1: Do not trust free cluster count in the FSINFO.
|
||||
/ bit1=0: Use last allocated cluster number in the FSINFO if available.
|
||||
/ bit1=1: Do not trust last allocated cluster number in the FSINFO.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ System Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_FS_TINY (!CONFIG_FATFS_PER_FILE_CACHE)
|
||||
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
|
||||
/ At the tiny configuration, size of file object (FIL) is shrinked FF_MAX_SS bytes.
|
||||
/ Instead of private sector buffer eliminated from the file object, common sector
|
||||
/ buffer in the filesystem object (FATFS) is used for the file data transfer. */
|
||||
|
||||
|
||||
#define FF_FS_EXFAT 0
|
||||
/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable)
|
||||
/ When enable exFAT, also LFN needs to be enabled.
|
||||
/ Note that enabling exFAT discards ANSI C (C89) compatibility. */
|
||||
|
||||
|
||||
#define FF_FS_NORTC 0
|
||||
#define FF_NORTC_MON 1
|
||||
#define FF_NORTC_MDAY 1
|
||||
#define FF_NORTC_YEAR 2017
|
||||
/* The option FF_FS_NORTC switches timestamp functiton. If the system does not have
|
||||
/ any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable
|
||||
/ the timestamp function. All objects modified by FatFs will have a fixed timestamp
|
||||
/ defined by FF_NORTC_MON, FF_NORTC_MDAY and FF_NORTC_YEAR in local time.
|
||||
/ To enable timestamp function (FF_FS_NORTC = 0), get_fattime() function need to be
|
||||
/ added to the project to read current time form real-time clock. FF_NORTC_MON,
|
||||
/ FF_NORTC_MDAY and FF_NORTC_YEAR have no effect.
|
||||
/ These options have no effect at read-only configuration (FF_FS_READONLY = 1). */
|
||||
|
||||
|
||||
#define FF_FS_LOCK CONFIG_FATFS_FS_LOCK
|
||||
/* The option FF_FS_LOCK switches file lock function to control duplicated file open
|
||||
/ and illegal operation to open objects. This option must be 0 when FF_FS_READONLY
|
||||
/ is 1.
|
||||
/
|
||||
/ 0: Disable file lock function. To avoid volume corruption, application program
|
||||
/ should avoid illegal open, remove and rename to the open objects.
|
||||
/ >0: Enable file lock function. The value defines how many files/sub-directories
|
||||
/ can be opened simultaneously under file lock control. Note that the file
|
||||
/ lock control is independent of re-entrancy. */
|
||||
|
||||
|
||||
#define FF_FS_REENTRANT 1
|
||||
#define FF_FS_TIMEOUT (CONFIG_FATFS_TIMEOUT_MS / portTICK_PERIOD_MS)
|
||||
#define FF_SYNC_t SemaphoreHandle_t
|
||||
/* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs
|
||||
/ module itself. Note that regardless of this option, file access to different
|
||||
/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
|
||||
/ and f_fdisk() function, are always not re-entrant. Only file/directory access
|
||||
/ to the same volume is under control of this function.
|
||||
/
|
||||
/ 0: Disable re-entrancy. FF_FS_TIMEOUT and FF_SYNC_t have no effect.
|
||||
/ 1: Enable re-entrancy. Also user provided synchronization handlers,
|
||||
/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
|
||||
/ function, must be added to the project. Samples are available in
|
||||
/ option/syscall.c.
|
||||
/
|
||||
/ The FF_FS_TIMEOUT defines timeout period in unit of time tick.
|
||||
/ The FF_SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
|
||||
/ SemaphoreHandle_t and etc. A header file for O/S definitions needs to be
|
||||
/ included somewhere in the scope of ff.h. */
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
|
||||
/*--- End of configuration options ---*/
|
||||
|
@ -1,38 +1,38 @@
|
||||
/*-------------------------------------------*/
|
||||
/* Integer type definitions for FatFs module */
|
||||
/*-------------------------------------------*/
|
||||
|
||||
#ifndef FF_INTEGER
|
||||
#define FF_INTEGER
|
||||
|
||||
#ifdef _WIN32 /* FatFs development platform */
|
||||
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
typedef unsigned __int64 QWORD;
|
||||
|
||||
|
||||
#else /* Embedded platform */
|
||||
|
||||
/* These types MUST be 16-bit or 32-bit */
|
||||
typedef int INT;
|
||||
typedef unsigned int UINT;
|
||||
|
||||
/* This type MUST be 8-bit */
|
||||
typedef unsigned char BYTE;
|
||||
|
||||
/* These types MUST be 16-bit */
|
||||
typedef short SHORT;
|
||||
typedef unsigned short WORD;
|
||||
typedef unsigned short WCHAR;
|
||||
|
||||
/* These types MUST be 32-bit */
|
||||
typedef long LONG;
|
||||
typedef unsigned long DWORD;
|
||||
|
||||
/* This type MUST be 64-bit (Remove this for ANSI C (C89) compatibility) */
|
||||
typedef unsigned long long QWORD;
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/*-------------------------------------------*/
|
||||
/* Integer type definitions for FatFs module */
|
||||
/*-------------------------------------------*/
|
||||
|
||||
#ifndef FF_INTEGER
|
||||
#define FF_INTEGER
|
||||
|
||||
#ifdef _WIN32 /* FatFs development platform */
|
||||
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
typedef unsigned __int64 QWORD;
|
||||
|
||||
|
||||
#else /* Embedded platform */
|
||||
|
||||
/* These types MUST be 16-bit or 32-bit */
|
||||
typedef int INT;
|
||||
typedef unsigned int UINT;
|
||||
|
||||
/* This type MUST be 8-bit */
|
||||
typedef unsigned char BYTE;
|
||||
|
||||
/* These types MUST be 16-bit */
|
||||
typedef short SHORT;
|
||||
typedef unsigned short WORD;
|
||||
typedef unsigned short WCHAR;
|
||||
|
||||
/* These types MUST be 32-bit */
|
||||
typedef long LONG;
|
||||
typedef unsigned long DWORD;
|
||||
|
||||
/* This type MUST be 64-bit (Remove this for ANSI C (C89) compatibility) */
|
||||
typedef unsigned long long QWORD;
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -1,52 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SYS_ARCH_H__
|
||||
#define __SYS_ARCH_H__
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/semphr.h"
|
||||
/*
|
||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SYS_ARCH_H__
|
||||
#define __SYS_ARCH_H__
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "arch/vfs_lwip.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef xSemaphoreHandle sys_sem_t;
|
||||
typedef xSemaphoreHandle sys_mutex_t;
|
||||
typedef xTaskHandle sys_thread_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef xSemaphoreHandle sys_sem_t;
|
||||
typedef xSemaphoreHandle sys_mutex_t;
|
||||
typedef xTaskHandle sys_thread_t;
|
||||
|
||||
typedef struct sys_mbox_s {
|
||||
xQueueHandle os_mbox;
|
||||
@ -54,28 +54,28 @@ typedef struct sys_mbox_s {
|
||||
uint8_t alive;
|
||||
}* sys_mbox_t;
|
||||
|
||||
|
||||
#define LWIP_COMPAT_MUTEX 0
|
||||
|
||||
#if !LWIP_COMPAT_MUTEX
|
||||
#define sys_mutex_valid( x ) ( ( ( *x ) == NULL) ? pdFALSE : pdTRUE )
|
||||
#define sys_mutex_set_invalid( x ) ( ( *x ) = NULL )
|
||||
#endif
|
||||
|
||||
#define sys_mbox_valid( x ) ( ( ( *x ) == NULL) ? pdFALSE : pdTRUE )
|
||||
#define sys_mbox_set_invalid( x ) ( ( *x ) = NULL )
|
||||
|
||||
#define sys_sem_valid( x ) ( ( ( *x ) == NULL) ? pdFALSE : pdTRUE )
|
||||
#define sys_sem_set_invalid( x ) ( ( *x ) = NULL )
|
||||
|
||||
#define LWIP_COMPAT_MUTEX 0
|
||||
|
||||
#if !LWIP_COMPAT_MUTEX
|
||||
#define sys_mutex_valid( x ) ( ( ( *x ) == NULL) ? pdFALSE : pdTRUE )
|
||||
#define sys_mutex_set_invalid( x ) ( ( *x ) = NULL )
|
||||
#endif
|
||||
|
||||
#define sys_mbox_valid( x ) ( ( ( *x ) == NULL) ? pdFALSE : pdTRUE )
|
||||
#define sys_mbox_set_invalid( x ) ( ( *x ) = NULL )
|
||||
|
||||
#define sys_sem_valid( x ) ( ( ( *x ) == NULL) ? pdFALSE : pdTRUE )
|
||||
#define sys_sem_set_invalid( x ) ( ( *x ) = NULL )
|
||||
|
||||
void sys_delay_ms(uint32_t ms);
|
||||
sys_sem_t* sys_thread_sem_init(void);
|
||||
void sys_thread_sem_deinit(void);
|
||||
sys_sem_t* sys_thread_sem_get(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
sys_sem_t* sys_thread_sem_get(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __SYS_ARCH_H__ */
|
||||
|
||||
#endif /* __SYS_ARCH_H__ */
|
||||
|
||||
|
@ -1,111 +1,111 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _X509_VFY_H_
|
||||
#define _X509_VFY_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define X509_V_OK 0
|
||||
#define X509_V_ERR_UNSPECIFIED 1
|
||||
#define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT 2
|
||||
#define X509_V_ERR_UNABLE_TO_GET_CRL 3
|
||||
#define X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE 4
|
||||
#define X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE 5
|
||||
#define X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY 6
|
||||
#define X509_V_ERR_CERT_SIGNATURE_FAILURE 7
|
||||
#define X509_V_ERR_CRL_SIGNATURE_FAILURE 8
|
||||
#define X509_V_ERR_CERT_NOT_YET_VALID 9
|
||||
#define X509_V_ERR_CERT_HAS_EXPIRED 10
|
||||
#define X509_V_ERR_CRL_NOT_YET_VALID 11
|
||||
#define X509_V_ERR_CRL_HAS_EXPIRED 12
|
||||
#define X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD 13
|
||||
#define X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD 14
|
||||
#define X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD 15
|
||||
#define X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD 16
|
||||
#define X509_V_ERR_OUT_OF_MEM 17
|
||||
#define X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT 18
|
||||
#define X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN 19
|
||||
#define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY 20
|
||||
#define X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE 21
|
||||
#define X509_V_ERR_CERT_CHAIN_TOO_LONG 22
|
||||
#define X509_V_ERR_CERT_REVOKED 23
|
||||
#define X509_V_ERR_INVALID_CA 24
|
||||
#define X509_V_ERR_PATH_LENGTH_EXCEEDED 25
|
||||
#define X509_V_ERR_INVALID_PURPOSE 26
|
||||
#define X509_V_ERR_CERT_UNTRUSTED 27
|
||||
#define X509_V_ERR_CERT_REJECTED 28
|
||||
/* These are 'informational' when looking for issuer cert */
|
||||
#define X509_V_ERR_SUBJECT_ISSUER_MISMATCH 29
|
||||
#define X509_V_ERR_AKID_SKID_MISMATCH 30
|
||||
#define X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH 31
|
||||
#define X509_V_ERR_KEYUSAGE_NO_CERTSIGN 32
|
||||
#define X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER 33
|
||||
#define X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION 34
|
||||
#define X509_V_ERR_KEYUSAGE_NO_CRL_SIGN 35
|
||||
#define X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION 36
|
||||
#define X509_V_ERR_INVALID_NON_CA 37
|
||||
#define X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED 38
|
||||
#define X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE 39
|
||||
#define X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED 40
|
||||
#define X509_V_ERR_INVALID_EXTENSION 41
|
||||
#define X509_V_ERR_INVALID_POLICY_EXTENSION 42
|
||||
#define X509_V_ERR_NO_EXPLICIT_POLICY 43
|
||||
#define X509_V_ERR_DIFFERENT_CRL_SCOPE 44
|
||||
#define X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE 45
|
||||
#define X509_V_ERR_UNNESTED_RESOURCE 46
|
||||
#define X509_V_ERR_PERMITTED_VIOLATION 47
|
||||
#define X509_V_ERR_EXCLUDED_VIOLATION 48
|
||||
#define X509_V_ERR_SUBTREE_MINMAX 49
|
||||
/* The application is not happy */
|
||||
#define X509_V_ERR_APPLICATION_VERIFICATION 50
|
||||
#define X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE 51
|
||||
#define X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX 52
|
||||
#define X509_V_ERR_UNSUPPORTED_NAME_SYNTAX 53
|
||||
#define X509_V_ERR_CRL_PATH_VALIDATION_ERROR 54
|
||||
/* Another issuer check debug option */
|
||||
#define X509_V_ERR_PATH_LOOP 55
|
||||
/* Suite B mode algorithm violation */
|
||||
#define X509_V_ERR_SUITE_B_INVALID_VERSION 56
|
||||
#define X509_V_ERR_SUITE_B_INVALID_ALGORITHM 57
|
||||
#define X509_V_ERR_SUITE_B_INVALID_CURVE 58
|
||||
#define X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM 59
|
||||
#define X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED 60
|
||||
#define X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 61
|
||||
/* Host, email and IP check errors */
|
||||
#define X509_V_ERR_HOSTNAME_MISMATCH 62
|
||||
#define X509_V_ERR_EMAIL_MISMATCH 63
|
||||
#define X509_V_ERR_IP_ADDRESS_MISMATCH 64
|
||||
/* DANE TLSA errors */
|
||||
#define X509_V_ERR_DANE_NO_MATCH 65
|
||||
/* security level errors */
|
||||
#define X509_V_ERR_EE_KEY_TOO_SMALL 66
|
||||
#define X509_V_ERR_CA_KEY_TOO_SMALL 67
|
||||
#define X509_V_ERR_CA_MD_TOO_WEAK 68
|
||||
/* Caller error */
|
||||
#define X509_V_ERR_INVALID_CALL 69
|
||||
/* Issuer lookup error */
|
||||
#define X509_V_ERR_STORE_LOOKUP 70
|
||||
/* Certificate transparency */
|
||||
#define X509_V_ERR_NO_VALID_SCTS 71
|
||||
|
||||
#define X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION 72
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _X509_VFY_H_
|
||||
#define _X509_VFY_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define X509_V_OK 0
|
||||
#define X509_V_ERR_UNSPECIFIED 1
|
||||
#define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT 2
|
||||
#define X509_V_ERR_UNABLE_TO_GET_CRL 3
|
||||
#define X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE 4
|
||||
#define X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE 5
|
||||
#define X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY 6
|
||||
#define X509_V_ERR_CERT_SIGNATURE_FAILURE 7
|
||||
#define X509_V_ERR_CRL_SIGNATURE_FAILURE 8
|
||||
#define X509_V_ERR_CERT_NOT_YET_VALID 9
|
||||
#define X509_V_ERR_CERT_HAS_EXPIRED 10
|
||||
#define X509_V_ERR_CRL_NOT_YET_VALID 11
|
||||
#define X509_V_ERR_CRL_HAS_EXPIRED 12
|
||||
#define X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD 13
|
||||
#define X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD 14
|
||||
#define X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD 15
|
||||
#define X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD 16
|
||||
#define X509_V_ERR_OUT_OF_MEM 17
|
||||
#define X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT 18
|
||||
#define X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN 19
|
||||
#define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY 20
|
||||
#define X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE 21
|
||||
#define X509_V_ERR_CERT_CHAIN_TOO_LONG 22
|
||||
#define X509_V_ERR_CERT_REVOKED 23
|
||||
#define X509_V_ERR_INVALID_CA 24
|
||||
#define X509_V_ERR_PATH_LENGTH_EXCEEDED 25
|
||||
#define X509_V_ERR_INVALID_PURPOSE 26
|
||||
#define X509_V_ERR_CERT_UNTRUSTED 27
|
||||
#define X509_V_ERR_CERT_REJECTED 28
|
||||
/* These are 'informational' when looking for issuer cert */
|
||||
#define X509_V_ERR_SUBJECT_ISSUER_MISMATCH 29
|
||||
#define X509_V_ERR_AKID_SKID_MISMATCH 30
|
||||
#define X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH 31
|
||||
#define X509_V_ERR_KEYUSAGE_NO_CERTSIGN 32
|
||||
#define X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER 33
|
||||
#define X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION 34
|
||||
#define X509_V_ERR_KEYUSAGE_NO_CRL_SIGN 35
|
||||
#define X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION 36
|
||||
#define X509_V_ERR_INVALID_NON_CA 37
|
||||
#define X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED 38
|
||||
#define X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE 39
|
||||
#define X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED 40
|
||||
#define X509_V_ERR_INVALID_EXTENSION 41
|
||||
#define X509_V_ERR_INVALID_POLICY_EXTENSION 42
|
||||
#define X509_V_ERR_NO_EXPLICIT_POLICY 43
|
||||
#define X509_V_ERR_DIFFERENT_CRL_SCOPE 44
|
||||
#define X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE 45
|
||||
#define X509_V_ERR_UNNESTED_RESOURCE 46
|
||||
#define X509_V_ERR_PERMITTED_VIOLATION 47
|
||||
#define X509_V_ERR_EXCLUDED_VIOLATION 48
|
||||
#define X509_V_ERR_SUBTREE_MINMAX 49
|
||||
/* The application is not happy */
|
||||
#define X509_V_ERR_APPLICATION_VERIFICATION 50
|
||||
#define X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE 51
|
||||
#define X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX 52
|
||||
#define X509_V_ERR_UNSUPPORTED_NAME_SYNTAX 53
|
||||
#define X509_V_ERR_CRL_PATH_VALIDATION_ERROR 54
|
||||
/* Another issuer check debug option */
|
||||
#define X509_V_ERR_PATH_LOOP 55
|
||||
/* Suite B mode algorithm violation */
|
||||
#define X509_V_ERR_SUITE_B_INVALID_VERSION 56
|
||||
#define X509_V_ERR_SUITE_B_INVALID_ALGORITHM 57
|
||||
#define X509_V_ERR_SUITE_B_INVALID_CURVE 58
|
||||
#define X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM 59
|
||||
#define X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED 60
|
||||
#define X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 61
|
||||
/* Host, email and IP check errors */
|
||||
#define X509_V_ERR_HOSTNAME_MISMATCH 62
|
||||
#define X509_V_ERR_EMAIL_MISMATCH 63
|
||||
#define X509_V_ERR_IP_ADDRESS_MISMATCH 64
|
||||
/* DANE TLSA errors */
|
||||
#define X509_V_ERR_DANE_NO_MATCH 65
|
||||
/* security level errors */
|
||||
#define X509_V_ERR_EE_KEY_TOO_SMALL 66
|
||||
#define X509_V_ERR_CA_KEY_TOO_SMALL 67
|
||||
#define X509_V_ERR_CA_MD_TOO_WEAK 68
|
||||
/* Caller error */
|
||||
#define X509_V_ERR_INVALID_CALL 69
|
||||
/* Issuer lookup error */
|
||||
#define X509_V_ERR_STORE_LOOKUP 70
|
||||
/* Certificate transparency */
|
||||
#define X509_V_ERR_NO_VALID_SCTS 71
|
||||
|
||||
#define X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION 72
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,136 +1,136 @@
|
||||
// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _wear_levelling_H_
|
||||
#define _wear_levelling_H_
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "esp_partition.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief wear levelling handle
|
||||
*/
|
||||
typedef int32_t wl_handle_t;
|
||||
|
||||
#define WL_INVALID_HANDLE -1
|
||||
|
||||
/**
|
||||
* @brief Mount WL for defined partition
|
||||
*
|
||||
* @param partition that will be used for access
|
||||
* @param out_handle handle of the WL instance
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK, if the allocation was successfully;
|
||||
* - ESP_ERR_INVALID_ARG, if WL allocation was unsuccessful;
|
||||
* - ESP_ERR_NO_MEM, if there was no memory to allocate WL components;
|
||||
*/
|
||||
esp_err_t wl_mount(const esp_partition_t *partition, wl_handle_t *out_handle);
|
||||
|
||||
/**
|
||||
* @brief Unmount WL for defined partition
|
||||
*
|
||||
* @param handle WL partition handle
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK, if the operation completed successfully;
|
||||
* - or one of error codes from lower-level flash driver.
|
||||
*/
|
||||
esp_err_t wl_unmount(wl_handle_t handle);
|
||||
|
||||
/**
|
||||
* @brief Erase part of the WL storage
|
||||
*
|
||||
* @param handle WL handle that are related to the partition
|
||||
* @param start_addr Address where erase operation should start. Must be aligned
|
||||
* to the result of function wl_sector_size(...).
|
||||
* @param size Size of the range which should be erased, in bytes.
|
||||
* Must be divisible by result of function wl_sector_size(...)..
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK, if the range was erased successfully;
|
||||
* - ESP_ERR_INVALID_ARG, if iterator or dst are NULL;
|
||||
* - ESP_ERR_INVALID_SIZE, if erase would go out of bounds of the partition;
|
||||
* - or one of error codes from lower-level flash driver.
|
||||
*/
|
||||
esp_err_t wl_erase_range(wl_handle_t handle, size_t start_addr, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Write data to the WL storage
|
||||
*
|
||||
* Before writing data to flash, corresponding region of flash needs to be erased.
|
||||
* This can be done using wl_erase_range function.
|
||||
*
|
||||
* @param handle WL handle that are related to the partition
|
||||
* @param dest_addr Address where the data should be written, relative to the
|
||||
* beginning of the partition.
|
||||
* @param src Pointer to the source buffer. Pointer must be non-NULL and
|
||||
* buffer must be at least 'size' bytes long.
|
||||
* @param size Size of data to be written, in bytes.
|
||||
*
|
||||
* @note Prior to writing to WL storage, make sure it has been erased with
|
||||
* wl_erase_range call.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK, if data was written successfully;
|
||||
* - ESP_ERR_INVALID_ARG, if dst_offset exceeds partition size;
|
||||
* - ESP_ERR_INVALID_SIZE, if write would go out of bounds of the partition;
|
||||
* - or one of error codes from lower-level flash driver.
|
||||
*/
|
||||
esp_err_t wl_write(wl_handle_t handle, size_t dest_addr, const void *src, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Read data from the WL storage
|
||||
*
|
||||
* @param handle WL module instance that was initialized before
|
||||
* @param dest Pointer to the buffer where data should be stored.
|
||||
* Pointer must be non-NULL and buffer must be at least 'size' bytes long.
|
||||
* @param src_addr Address of the data to be read, relative to the
|
||||
* beginning of the partition.
|
||||
* @param size Size of data to be read, in bytes.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK, if data was read successfully;
|
||||
* - ESP_ERR_INVALID_ARG, if src_offset exceeds partition size;
|
||||
* - ESP_ERR_INVALID_SIZE, if read would go out of bounds of the partition;
|
||||
* - or one of error codes from lower-level flash driver.
|
||||
*/
|
||||
esp_err_t wl_read(wl_handle_t handle, size_t src_addr, void *dest, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Get size of the WL storage
|
||||
*
|
||||
* @param handle WL module handle that was initialized before
|
||||
* @return usable size, in bytes
|
||||
*/
|
||||
size_t wl_size(wl_handle_t handle);
|
||||
|
||||
/**
|
||||
* @brief Get sector size of the WL instance
|
||||
*
|
||||
* @param handle WL module handle that was initialized before
|
||||
* @return sector size, in bytes
|
||||
*/
|
||||
size_t wl_sector_size(wl_handle_t handle);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // _wear_levelling_H_
|
||||
// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _wear_levelling_H_
|
||||
#define _wear_levelling_H_
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "esp_partition.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief wear levelling handle
|
||||
*/
|
||||
typedef int32_t wl_handle_t;
|
||||
|
||||
#define WL_INVALID_HANDLE -1
|
||||
|
||||
/**
|
||||
* @brief Mount WL for defined partition
|
||||
*
|
||||
* @param partition that will be used for access
|
||||
* @param out_handle handle of the WL instance
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK, if the allocation was successfully;
|
||||
* - ESP_ERR_INVALID_ARG, if WL allocation was unsuccessful;
|
||||
* - ESP_ERR_NO_MEM, if there was no memory to allocate WL components;
|
||||
*/
|
||||
esp_err_t wl_mount(const esp_partition_t *partition, wl_handle_t *out_handle);
|
||||
|
||||
/**
|
||||
* @brief Unmount WL for defined partition
|
||||
*
|
||||
* @param handle WL partition handle
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK, if the operation completed successfully;
|
||||
* - or one of error codes from lower-level flash driver.
|
||||
*/
|
||||
esp_err_t wl_unmount(wl_handle_t handle);
|
||||
|
||||
/**
|
||||
* @brief Erase part of the WL storage
|
||||
*
|
||||
* @param handle WL handle that are related to the partition
|
||||
* @param start_addr Address where erase operation should start. Must be aligned
|
||||
* to the result of function wl_sector_size(...).
|
||||
* @param size Size of the range which should be erased, in bytes.
|
||||
* Must be divisible by result of function wl_sector_size(...)..
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK, if the range was erased successfully;
|
||||
* - ESP_ERR_INVALID_ARG, if iterator or dst are NULL;
|
||||
* - ESP_ERR_INVALID_SIZE, if erase would go out of bounds of the partition;
|
||||
* - or one of error codes from lower-level flash driver.
|
||||
*/
|
||||
esp_err_t wl_erase_range(wl_handle_t handle, size_t start_addr, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Write data to the WL storage
|
||||
*
|
||||
* Before writing data to flash, corresponding region of flash needs to be erased.
|
||||
* This can be done using wl_erase_range function.
|
||||
*
|
||||
* @param handle WL handle that are related to the partition
|
||||
* @param dest_addr Address where the data should be written, relative to the
|
||||
* beginning of the partition.
|
||||
* @param src Pointer to the source buffer. Pointer must be non-NULL and
|
||||
* buffer must be at least 'size' bytes long.
|
||||
* @param size Size of data to be written, in bytes.
|
||||
*
|
||||
* @note Prior to writing to WL storage, make sure it has been erased with
|
||||
* wl_erase_range call.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK, if data was written successfully;
|
||||
* - ESP_ERR_INVALID_ARG, if dst_offset exceeds partition size;
|
||||
* - ESP_ERR_INVALID_SIZE, if write would go out of bounds of the partition;
|
||||
* - or one of error codes from lower-level flash driver.
|
||||
*/
|
||||
esp_err_t wl_write(wl_handle_t handle, size_t dest_addr, const void *src, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Read data from the WL storage
|
||||
*
|
||||
* @param handle WL module instance that was initialized before
|
||||
* @param dest Pointer to the buffer where data should be stored.
|
||||
* Pointer must be non-NULL and buffer must be at least 'size' bytes long.
|
||||
* @param src_addr Address of the data to be read, relative to the
|
||||
* beginning of the partition.
|
||||
* @param size Size of data to be read, in bytes.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK, if data was read successfully;
|
||||
* - ESP_ERR_INVALID_ARG, if src_offset exceeds partition size;
|
||||
* - ESP_ERR_INVALID_SIZE, if read would go out of bounds of the partition;
|
||||
* - or one of error codes from lower-level flash driver.
|
||||
*/
|
||||
esp_err_t wl_read(wl_handle_t handle, size_t src_addr, void *dest, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Get size of the WL storage
|
||||
*
|
||||
* @param handle WL module handle that was initialized before
|
||||
* @return usable size, in bytes
|
||||
*/
|
||||
size_t wl_size(wl_handle_t handle);
|
||||
|
||||
/**
|
||||
* @brief Get sector size of the WL instance
|
||||
*
|
||||
* @param handle WL module handle that was initialized before
|
||||
* @return sector size, in bytes
|
||||
*/
|
||||
size_t wl_sector_size(wl_handle_t handle);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // _wear_levelling_H_
|
||||
|
@ -1,64 +1,64 @@
|
||||
#ifndef Pins_Arduino_h
|
||||
#define Pins_Arduino_h
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define EXTERNAL_NUM_INTERRUPTS 16
|
||||
#define NUM_DIGITAL_PINS 40
|
||||
#define NUM_ANALOG_INPUTS 16
|
||||
|
||||
#define analogInputToDigitalPin(p) (((p)<20)?(esp32_adc2gpio[(p)]):-1)
|
||||
#define digitalPinToInterrupt(p) (((p)<40)?(p):-1)
|
||||
#define digitalPinHasPWM(p) (p < 34)
|
||||
|
||||
static const uint8_t LED_BUILTIN = 25;
|
||||
#define BUILTIN_LED LED_BUILTIN // backward compatibility
|
||||
|
||||
static const uint8_t KEY_BUILTIN = 0;
|
||||
|
||||
static const uint8_t TX = 1;
|
||||
static const uint8_t RX = 3;
|
||||
|
||||
static const uint8_t SDA = 21;
|
||||
static const uint8_t SCL = 22;
|
||||
|
||||
static const uint8_t SS = 5;
|
||||
static const uint8_t MOSI = 23;
|
||||
static const uint8_t MISO = 19;
|
||||
static const uint8_t SCK = 18;
|
||||
|
||||
static const uint8_t A0 = 36;
|
||||
static const uint8_t A1 = 37;
|
||||
static const uint8_t A2 = 38;
|
||||
static const uint8_t A3 = 39;
|
||||
static const uint8_t A4 = 32;
|
||||
static const uint8_t A5 = 33;
|
||||
static const uint8_t A6 = 34;
|
||||
static const uint8_t A7 = 35;
|
||||
|
||||
static const uint8_t A10 = 4;
|
||||
static const uint8_t A11 = 0;
|
||||
static const uint8_t A12 = 2;
|
||||
static const uint8_t A13 = 15;
|
||||
static const uint8_t A14 = 13;
|
||||
static const uint8_t A15 = 12;
|
||||
static const uint8_t A16 = 14;
|
||||
static const uint8_t A17 = 27;
|
||||
static const uint8_t A18 = 25;
|
||||
static const uint8_t A19 = 26;
|
||||
|
||||
static const uint8_t T0 = 4;
|
||||
static const uint8_t T1 = 0;
|
||||
static const uint8_t T2 = 2;
|
||||
static const uint8_t T3 = 15;
|
||||
static const uint8_t T4 = 13;
|
||||
static const uint8_t T5 = 12;
|
||||
static const uint8_t T6 = 14;
|
||||
static const uint8_t T7 = 27;
|
||||
static const uint8_t T8 = 33;
|
||||
static const uint8_t T9 = 32;
|
||||
|
||||
static const uint8_t DAC1 = 25;
|
||||
static const uint8_t DAC2 = 26;
|
||||
|
||||
#endif /* Pins_Arduino_h */
|
||||
#ifndef Pins_Arduino_h
|
||||
#define Pins_Arduino_h
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define EXTERNAL_NUM_INTERRUPTS 16
|
||||
#define NUM_DIGITAL_PINS 40
|
||||
#define NUM_ANALOG_INPUTS 16
|
||||
|
||||
#define analogInputToDigitalPin(p) (((p)<20)?(esp32_adc2gpio[(p)]):-1)
|
||||
#define digitalPinToInterrupt(p) (((p)<40)?(p):-1)
|
||||
#define digitalPinHasPWM(p) (p < 34)
|
||||
|
||||
static const uint8_t LED_BUILTIN = 25;
|
||||
#define BUILTIN_LED LED_BUILTIN // backward compatibility
|
||||
|
||||
static const uint8_t KEY_BUILTIN = 0;
|
||||
|
||||
static const uint8_t TX = 1;
|
||||
static const uint8_t RX = 3;
|
||||
|
||||
static const uint8_t SDA = 21;
|
||||
static const uint8_t SCL = 22;
|
||||
|
||||
static const uint8_t SS = 5;
|
||||
static const uint8_t MOSI = 23;
|
||||
static const uint8_t MISO = 19;
|
||||
static const uint8_t SCK = 18;
|
||||
|
||||
static const uint8_t A0 = 36;
|
||||
static const uint8_t A1 = 37;
|
||||
static const uint8_t A2 = 38;
|
||||
static const uint8_t A3 = 39;
|
||||
static const uint8_t A4 = 32;
|
||||
static const uint8_t A5 = 33;
|
||||
static const uint8_t A6 = 34;
|
||||
static const uint8_t A7 = 35;
|
||||
|
||||
static const uint8_t A10 = 4;
|
||||
static const uint8_t A11 = 0;
|
||||
static const uint8_t A12 = 2;
|
||||
static const uint8_t A13 = 15;
|
||||
static const uint8_t A14 = 13;
|
||||
static const uint8_t A15 = 12;
|
||||
static const uint8_t A16 = 14;
|
||||
static const uint8_t A17 = 27;
|
||||
static const uint8_t A18 = 25;
|
||||
static const uint8_t A19 = 26;
|
||||
|
||||
static const uint8_t T0 = 4;
|
||||
static const uint8_t T1 = 0;
|
||||
static const uint8_t T2 = 2;
|
||||
static const uint8_t T3 = 15;
|
||||
static const uint8_t T4 = 13;
|
||||
static const uint8_t T5 = 12;
|
||||
static const uint8_t T6 = 14;
|
||||
static const uint8_t T7 = 27;
|
||||
static const uint8_t T8 = 33;
|
||||
static const uint8_t T9 = 32;
|
||||
|
||||
static const uint8_t DAC1 = 25;
|
||||
static const uint8_t DAC2 = 26;
|
||||
|
||||
#endif /* Pins_Arduino_h */
|
||||
|
@ -1,64 +1,64 @@
|
||||
#ifndef Pins_Arduino_h
|
||||
#define Pins_Arduino_h
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define EXTERNAL_NUM_INTERRUPTS 16
|
||||
#define NUM_DIGITAL_PINS 40
|
||||
#define NUM_ANALOG_INPUTS 16
|
||||
|
||||
#define analogInputToDigitalPin(p) (((p)<20)?(esp32_adc2gpio[(p)]):-1)
|
||||
#define digitalPinToInterrupt(p) (((p)<40)?(p):-1)
|
||||
#define digitalPinHasPWM(p) (p < 34)
|
||||
|
||||
static const uint8_t LED_BUILTIN = 25;
|
||||
#define BUILTIN_LED LED_BUILTIN // backward compatibility
|
||||
|
||||
static const uint8_t KEY_BUILTIN = 0;
|
||||
|
||||
static const uint8_t TX = 1;
|
||||
static const uint8_t RX = 3;
|
||||
|
||||
static const uint8_t SDA = 21;
|
||||
static const uint8_t SCL = 22;
|
||||
|
||||
static const uint8_t SS = 18;
|
||||
static const uint8_t MOSI = 27;
|
||||
static const uint8_t MISO = 19;
|
||||
static const uint8_t SCK = 5;
|
||||
|
||||
static const uint8_t A0 = 36;
|
||||
static const uint8_t A1 = 37;
|
||||
static const uint8_t A2 = 38;
|
||||
static const uint8_t A3 = 39;
|
||||
static const uint8_t A4 = 32;
|
||||
static const uint8_t A5 = 33;
|
||||
static const uint8_t A6 = 34;
|
||||
static const uint8_t A7 = 35;
|
||||
|
||||
static const uint8_t A10 = 4;
|
||||
static const uint8_t A11 = 0;
|
||||
static const uint8_t A12 = 2;
|
||||
static const uint8_t A13 = 15;
|
||||
static const uint8_t A14 = 13;
|
||||
static const uint8_t A15 = 12;
|
||||
static const uint8_t A16 = 14;
|
||||
static const uint8_t A17 = 27;
|
||||
static const uint8_t A18 = 25;
|
||||
static const uint8_t A19 = 26;
|
||||
|
||||
static const uint8_t T0 = 4;
|
||||
static const uint8_t T1 = 0;
|
||||
static const uint8_t T2 = 2;
|
||||
static const uint8_t T3 = 15;
|
||||
static const uint8_t T4 = 13;
|
||||
static const uint8_t T5 = 12;
|
||||
static const uint8_t T6 = 14;
|
||||
static const uint8_t T7 = 27;
|
||||
static const uint8_t T8 = 32;
|
||||
static const uint8_t T9 = 33;
|
||||
|
||||
static const uint8_t DAC1 = 26;
|
||||
static const uint8_t DAC2 = 25;
|
||||
|
||||
#endif /* Pins_Arduino_h */
|
||||
#ifndef Pins_Arduino_h
|
||||
#define Pins_Arduino_h
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define EXTERNAL_NUM_INTERRUPTS 16
|
||||
#define NUM_DIGITAL_PINS 40
|
||||
#define NUM_ANALOG_INPUTS 16
|
||||
|
||||
#define analogInputToDigitalPin(p) (((p)<20)?(esp32_adc2gpio[(p)]):-1)
|
||||
#define digitalPinToInterrupt(p) (((p)<40)?(p):-1)
|
||||
#define digitalPinHasPWM(p) (p < 34)
|
||||
|
||||
static const uint8_t LED_BUILTIN = 25;
|
||||
#define BUILTIN_LED LED_BUILTIN // backward compatibility
|
||||
|
||||
static const uint8_t KEY_BUILTIN = 0;
|
||||
|
||||
static const uint8_t TX = 1;
|
||||
static const uint8_t RX = 3;
|
||||
|
||||
static const uint8_t SDA = 21;
|
||||
static const uint8_t SCL = 22;
|
||||
|
||||
static const uint8_t SS = 18;
|
||||
static const uint8_t MOSI = 27;
|
||||
static const uint8_t MISO = 19;
|
||||
static const uint8_t SCK = 5;
|
||||
|
||||
static const uint8_t A0 = 36;
|
||||
static const uint8_t A1 = 37;
|
||||
static const uint8_t A2 = 38;
|
||||
static const uint8_t A3 = 39;
|
||||
static const uint8_t A4 = 32;
|
||||
static const uint8_t A5 = 33;
|
||||
static const uint8_t A6 = 34;
|
||||
static const uint8_t A7 = 35;
|
||||
|
||||
static const uint8_t A10 = 4;
|
||||
static const uint8_t A11 = 0;
|
||||
static const uint8_t A12 = 2;
|
||||
static const uint8_t A13 = 15;
|
||||
static const uint8_t A14 = 13;
|
||||
static const uint8_t A15 = 12;
|
||||
static const uint8_t A16 = 14;
|
||||
static const uint8_t A17 = 27;
|
||||
static const uint8_t A18 = 25;
|
||||
static const uint8_t A19 = 26;
|
||||
|
||||
static const uint8_t T0 = 4;
|
||||
static const uint8_t T1 = 0;
|
||||
static const uint8_t T2 = 2;
|
||||
static const uint8_t T3 = 15;
|
||||
static const uint8_t T4 = 13;
|
||||
static const uint8_t T5 = 12;
|
||||
static const uint8_t T6 = 14;
|
||||
static const uint8_t T7 = 27;
|
||||
static const uint8_t T8 = 32;
|
||||
static const uint8_t T9 = 33;
|
||||
|
||||
static const uint8_t DAC1 = 26;
|
||||
static const uint8_t DAC2 = 25;
|
||||
|
||||
#endif /* Pins_Arduino_h */
|
||||
|
Loading…
x
Reference in New Issue
Block a user