Compare commits

...

11 Commits

Author SHA1 Message Date
4638628873 Wait for client.available() to prevent ESP32 crashes (#3154)
* Wait for client.available() to prevent ESP32 crashes

* Removed user-specific SSID & passphrase
2019-10-02 14:45:42 +03:00
6f70e27011 Base64::encode : const correctness / String by reference passing (#3314)
Avoid passing String by-value, which is slightly less efficient
as it involves a full copy-constructor/tempstring creation.
2019-10-02 14:29:24 +03:00
d0b064a1ee Update CI scripts for better error handling (#3316) 2019-10-02 11:58:02 +03:00
85c77a9c3f Fix CI Builds for Linux (#3313) 2019-10-01 23:13:08 +03:00
c8e3f0c732 Support Pi 4 on 64bit kernel 2019-10-01 22:15:13 +03:00
5ad468f9dc Add ARM toolchain 2019-10-01 21:48:03 +03:00
38c4c06108 Support for Master mode, Pin and SSP (#3219)
* 20190916 - initial: support for Master mode, Pin and SSP

* 20190916 - initial: Add example app for Master mode

* 20190916 - initial: Force another build

* 20190916 - connect would use resolved address as preference and remove now redundant _remote_address

* 20190916 - rework set/reset/default pin logic

* 20190916 - cleanup: remove static vars, add/use constants, fix typos

* 20190916 - fix build issues and implement geoup events for status verification.

* 20190916 - remove extra lines,misc

* 20190916 - rework ESP_BT_GAP_DISC_RES_EVT, added SPP_DISCONNECTED bit for disconnect event. + timeout for disconnect()

* 20190916 - Small log change to improve log sequencing

* 20190916 - remove static from local vars

* 20190916 - Limited scope and duration for the scan, log device address during scan in info mode as it is very difficult to find out sometimes. Fixed get_name_from_eir() not resetting the name when called.

* 20190916 - break property for loop during scan when name matches.

* 20190916 - misc

* 20190916 - SPP_DISCONNECT state updates

* 20190916 - formatting, remove some strange syntax from initiator code

* 20190916 - Add comments to the example about connect(...) usage and timeouts

* 20190916 - fix disconnect() without timeout

* 20190916 - Add example comment to view BT address and name during connect(name)

* 20190916 - wording in example comments

* 20190916 - rework connect() and disconnect() methods to help with concurrency and more authoritative status returned back to caller. Automatic disconnect in connect() methods

* 20190916 - optimize code

* 20190916 - optimize code - more

* 20190916 - add timeout for pin set

* 20190916 - change scan mode to ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE

* 20190916 - update example code slightly

* 20190916 - increase READY_TIMEOUT to 10 secs

* 20190916 - typo in example and move waitForConnect() to static area

* 20190916 - update example comments

* 20190916 - update example comments

* 20190916 - update example comments

* 20190916 - add new example to remove paired devices from ESP32

* 20190916 - correct typo in example

* 20190916 - update example comment, add remove_bond_device() method for convenience.

* 20190916 - reword example comment.

* 20190916 - rename remove_bond_device()

* 20190916 - rename removePairedDevice() to unpairDevice()

* 20190916 - code review changes

* 20190916 - fix return value in setup() od example
2019-10-01 17:34:46 +03:00
b334b2c2f9 Add config, menu partition Wrover (#3147)
* add config, menu partition Wrover

* fix all boards
2019-10-01 17:10:16 +03:00
8a46697168 Fix for issue_3209. (#3210)
#include "esp32-hal-log.h" is mandatory is order to build BLEDevice.cpp.
It can't be left up to a compiler variable.
2019-10-01 16:32:47 +03:00
270a2759d9 Add pages action (#3311)
* Add script to handle updates to the docs folder

* Create gh-pages.yml

* Update on-pages.sh
2019-10-01 16:04:20 +03:00
01d9345d28 Update development JSON location 2019-10-01 12:14:07 +03:00
18 changed files with 789 additions and 118 deletions

42
.github/scripts/install-arduino-core-esp32.sh vendored Normal file → Executable file
View File

@ -2,39 +2,33 @@
export ARDUINO_ESP32_PATH="$ARDUINO_USR_PATH/hardware/espressif/esp32"
if [ ! -d "$ARDUINO_ESP32_PATH" ]; then
echo "Installing ESP32 Arduino Core in '$ARDUINO_ESP32_PATH'..."
echo "Installing ESP32 Arduino Core ..."
script_init_path="$PWD"
mkdir -p "$ARDUINO_USR_PATH/hardware/espressif" && \
mkdir -p "$ARDUINO_USR_PATH/hardware/espressif"
cd "$ARDUINO_USR_PATH/hardware/espressif"
if [ $? -ne 0 ]; then exit 1; fi
if [ "$GITHUB_REPOSITORY" == "espressif/arduino-esp32" ]; then
echo "Linking Core..." && \
ln -s $GITHUB_WORKSPACE esp32
else
echo "Cloning Core Repository..." && \
git clone https://github.com/espressif/arduino-esp32.git esp32 > /dev/null 2>&1
if [ $? -ne 0 ]; then echo "ERROR: GIT clone failed"; exit 1; fi
fi
cd esp32 && \
echo "Updating submodules..." && \
git submodule update --init --recursive > /dev/null 2>&1
if [ $? -ne 0 ]; then echo "ERROR: Submodule update failed"; exit 1; fi
echo "Installing Python Serial..." && \
echo "Installing Python Serial ..."
pip install pyserial > /dev/null
if [ $? -ne 0 ]; then echo "ERROR: Install failed"; exit 1; fi
if [ "$OS_IS_WINDOWS" == "1" ]; then
echo "Installing Python Requests..."
echo "Installing Python Requests ..."
pip install requests > /dev/null
if [ $? -ne 0 ]; then echo "ERROR: Install failed"; exit 1; fi
fi
echo "Downloading the tools and the toolchain..."
cd tools && python get.py > /dev/null
if [ $? -ne 0 ]; then echo "ERROR: Download failed"; exit 1; fi
if [ "$GITHUB_REPOSITORY" == "espressif/arduino-esp32" ]; then
echo "Linking Core..."
ln -s $GITHUB_WORKSPACE esp32
else
echo "Cloning Core Repository..."
git clone https://github.com/espressif/arduino-esp32.git esp32 > /dev/null 2>&1
fi
echo "Updating Submodules ..."
cd esp32
git submodule update --init --recursive > /dev/null 2>&1
echo "Installing Platform Tools ..."
cd tools && python get.py
cd $script_init_path
echo "ESP32 Arduino has been installed in '$ARDUINO_ESP32_PATH'"

26
.github/scripts/install-arduino-ide.sh vendored Normal file → Executable file
View File

@ -12,7 +12,7 @@ if [[ "$OSTYPE" == "linux"* ]]; then
OS_NAME="linux32"
elif [[ "$OSBITS" == "x86_64" ]]; then
OS_NAME="linux64"
elif [[ "$OSBITS" == "armv7l" ]]; then
elif [[ "$OSBITS" == "armv7l" || "$OSBITS" == "aarch64" ]]; then
OS_NAME="linuxarm"
else
OS_NAME="$OSTYPE-$OSBITS"
@ -46,28 +46,23 @@ else
fi
if [ ! -d "$ARDUINO_IDE_PATH" ]; then
echo "Installing Arduino IDE on $OS_NAME..."
echo "Downloading 'arduino-nightly-$OS_NAME.$ARCHIVE_FORMAT' to 'arduino.$ARCHIVE_FORMAT'..."
echo "Installing Arduino IDE on $OS_NAME ..."
echo "Downloading 'arduino-nightly-$OS_NAME.$ARCHIVE_FORMAT' to 'arduino.$ARCHIVE_FORMAT' ..."
if [ "$OS_IS_LINUX" == "1" ]; then
wget -O "arduino.$ARCHIVE_FORMAT" "https://www.arduino.cc/download.php?f=/arduino-nightly-$OS_NAME.$ARCHIVE_FORMAT" > /dev/null 2>&1
if [ $? -ne 0 ]; then echo "ERROR: Download failed"; exit 1; fi
echo "Extracting 'arduino.$ARCHIVE_FORMAT'..."
echo "Extracting 'arduino.$ARCHIVE_FORMAT' ..."
tar xf "arduino.$ARCHIVE_FORMAT" > /dev/null
if [ $? -ne 0 ]; then exit 1; fi
mv arduino-nightly "$ARDUINO_IDE_PATH"
else
curl -o "arduino.$ARCHIVE_FORMAT" -L "https://www.arduino.cc/download.php?f=/arduino-nightly-$OS_NAME.$ARCHIVE_FORMAT" > /dev/null 2>&1
if [ $? -ne 0 ]; then echo "ERROR: Download failed"; exit 1; fi
echo "Extracting 'arduino.$ARCHIVE_FORMAT'..."
echo "Extracting 'arduino.$ARCHIVE_FORMAT' ..."
unzip "arduino.$ARCHIVE_FORMAT" > /dev/null
if [ $? -ne 0 ]; then exit 1; fi
if [ "$OS_IS_MACOS" == "1" ]; then
mv "Arduino.app" "/Applications/Arduino.app"
else
mv arduino-nightly "$ARDUINO_IDE_PATH"
fi
fi
if [ $? -ne 0 ]; then exit 1; fi
rm -rf "arduino.$ARCHIVE_FORMAT"
mkdir -p "$ARDUINO_USR_PATH/libraries"
@ -95,7 +90,7 @@ function build_sketch(){ # build_sketch <fqbn> <path-to-ino> [extra-options]
fi
echo ""
echo "Compiling '"$(basename "$sketch")"'..."
echo "Compiling '"$(basename "$sketch")"' ..."
mkdir -p "$ARDUINO_BUILD_DIR"
mkdir -p "$ARDUINO_CACHE_DIR"
$ARDUINO_IDE_PATH/arduino-builder -compile -logger=human -core-api-version=10810 \
@ -115,9 +110,13 @@ function build_sketch(){ # build_sketch <fqbn> <path-to-ino> [extra-options]
function count_sketches() # count_sketches <examples-path>
{
local examples="$1"
rm -rf sketches.txt
if [ ! -d "$examples" ]; then
touch sketches.txt
return 0
fi
local sketches=$(find $examples -name *.ino)
local sketchnum=0
rm -rf sketches.txt
for sketch in $sketches; do
local sketchdir=$(dirname $sketch)
local sketchdirname=$(basename $sketchdir)
@ -163,8 +162,10 @@ function build_sketches() # build_sketches <fqbn> <examples-path> <chunk> <total
return 1
fi
set +e
count_sketches "$examples"
local sketchcount=$?
set -e
local sketches=$(cat sketches.txt)
rm -rf sketches.txt
@ -214,4 +215,3 @@ function build_sketches() # build_sketches <fqbn> <examples-path> <chunk> <total
done
return 0
}

68
.github/scripts/install-platformio-esp32.sh vendored Normal file → Executable file
View File

@ -2,40 +2,34 @@
export PLATFORMIO_ESP32_PATH="$HOME/.platformio/packages/framework-arduinoespressif32"
echo "Installing Python Wheel..."
echo "Installing Python Wheel ..."
pip install wheel > /dev/null 2>&1
if [ $? -ne 0 ]; then echo "ERROR: Install failed"; exit 1; fi
echo "Installing PlatformIO..."
echo "Installing PlatformIO ..."
pip install -U https://github.com/platformio/platformio/archive/develop.zip > /dev/null 2>&1
if [ $? -ne 0 ]; then echo "ERROR: Install failed"; exit 1; fi
echo "Installing Platform ESP32..."
echo "Installing Platform ESP32 ..."
python -m platformio platform install https://github.com/platformio/platform-espressif32.git#feature/stage > /dev/null 2>&1
if [ $? -ne 0 ]; then echo "ERROR: Install failed"; exit 1; fi
echo "Replacing the framework version..."
echo "Replacing the framework version ..."
if [[ "$OSTYPE" == "darwin"* ]]; then
sed 's/https:\/\/github\.com\/espressif\/arduino-esp32\.git/*/' "$HOME/.platformio/platforms/espressif32/platform.json" > "platform.json" && \
sed 's/https:\/\/github\.com\/espressif\/arduino-esp32\.git/*/' "$HOME/.platformio/platforms/espressif32/platform.json" > "platform.json"
mv -f "platform.json" "$HOME/.platformio/platforms/espressif32/platform.json"
else
sed -i 's/https:\/\/github\.com\/espressif\/arduino-esp32\.git/*/' "$HOME/.platformio/platforms/espressif32/platform.json"
fi
if [ $? -ne 0 ]; then echo "ERROR: Replace failed"; exit 1; fi
if [ "$GITHUB_REPOSITORY" == "espressif/arduino-esp32" ]; then
echo "Linking Core..." && \
echo "Linking Core..."
ln -s $GITHUB_WORKSPACE "$PLATFORMIO_ESP32_PATH"
else
echo "Cloning Core Repository..." && \
echo "Cloning Core Repository ..."
git clone https://github.com/espressif/arduino-esp32.git "$PLATFORMIO_ESP32_PATH" > /dev/null 2>&1
if [ $? -ne 0 ]; then echo "ERROR: GIT clone failed"; exit 1; fi
fi
echo "PlatformIO for ESP32 has been installed"
echo ""
function build_pio_sketch(){ # build_pio_sketch <board> <path-to-ino>
if [ "$#" -lt 2 ]; then
echo "ERROR: Illegal number of parameters"
@ -43,20 +37,24 @@ function build_pio_sketch(){ # build_pio_sketch <board> <path-to-ino>
return 1
fi
local board="$1"
local sketch="$2"
local sketch_dir=$(dirname "$sketch")
echo ""
echo "Compiling '"$(basename "$sketch")"'..."
python -m platformio ci --board "$board" "$sketch_dir" --project-option="board_build.partitions = huge_app.csv"
local board="$1"
local sketch="$2"
local sketch_dir=$(dirname "$sketch")
echo ""
echo "Compiling '"$(basename "$sketch")"' ..."
python -m platformio ci --board "$board" "$sketch_dir" --project-option="board_build.partitions = huge_app.csv"
}
function count_sketches() # count_sketches <examples-path>
{
local examples="$1"
local examples="$1"
rm -rf sketches.txt
if [ ! -d "$examples" ]; then
touch sketches.txt
return 0
fi
local sketches=$(find $examples -name *.ino)
local sketchnum=0
rm -rf sketches.txt
for sketch in $sketches; do
local sketchdir=$(dirname $sketch)
local sketchdirname=$(basename $sketchdir)
@ -91,35 +89,37 @@ function build_pio_sketches() # build_pio_sketches <board> <examples-path> <chun
chunks_num="1"
fi
if [ "$chunks_num" -le 0 ]; then
echo "ERROR: Chunks count must be positive number"
return 1
fi
if [ "$chunk_idex" -ge "$chunks_num" ]; then
echo "ERROR: Chunk index must be less than chunks count"
return 1
fi
if [ "$chunks_num" -le 0 ]; then
echo "ERROR: Chunks count must be positive number"
return 1
fi
if [ "$chunk_idex" -ge "$chunks_num" ]; then
echo "ERROR: Chunk index must be less than chunks count"
return 1
fi
set +e
count_sketches "$examples"
local sketchcount=$?
set -e
local sketches=$(cat sketches.txt)
rm -rf sketches.txt
local chunk_size=$(( $sketchcount / $chunks_num ))
local all_chunks=$(( $chunks_num * $chunk_size ))
if [ "$all_chunks" -lt "$sketchcount" ]; then
chunk_size=$(( $chunk_size + 1 ))
chunk_size=$(( $chunk_size + 1 ))
fi
local start_index=$(( $chunk_idex * $chunk_size ))
if [ "$sketchcount" -le "$start_index" ]; then
echo "Skipping job"
return 0
echo "Skipping job"
return 0
fi
local end_index=$(( $(( $chunk_idex + 1 )) * $chunk_size ))
if [ "$end_index" -gt "$sketchcount" ]; then
end_index=$sketchcount
end_index=$sketchcount
fi
local start_num=$(( $start_index + 1 ))
@ -141,7 +141,7 @@ function build_pio_sketches() # build_pio_sketches <board> <examples-path> <chun
sketchnum=$(($sketchnum + 1))
if [ "$sketchnum" -le "$start_index" ] \
|| [ "$sketchnum" -gt "$end_index" ]; then
continue
continue
fi
build_pio_sketch "$board" "$sketch"
local result=$?

131
.github/scripts/on-pages.sh vendored Normal file
View File

@ -0,0 +1,131 @@
#/bin/bash
set -e
function get_file_size(){
local file="$1"
if [[ "$OSTYPE" == "darwin"* ]]; then
eval `stat -s "$file"`
local res="$?"
echo "$st_size"
return $res
else
stat --printf="%s" "$file"
return $?
fi
}
#git_remove_from_pages <file>
function git_remove_from_pages(){
local path=$1
local info=`curl -s -k -H "Authorization: token $GITHUB_TOKEN" -H "Accept: application/vnd.github.v3.object+json" -X GET "https://api.github.com/repos/$GITHUB_REPOSITORY/contents/$path?ref=gh-pages"`
local type=`echo "$info" | jq -r '.type'`
if [ ! $type == "file" ]; then
if [ ! $type == "null" ]; then
echo "Wrong type '$type'"
else
echo "File is not on Pages"
fi
return 0
fi
local sha=`echo "$info" | jq -r '.sha'`
local message="Deleting "$(basename $path)
local json="{\"branch\":\"gh-pages\",\"message\":\"$message\",\"sha\":\"$sha\"}"
echo "$json" | curl -s -k -H "Authorization: token $GITHUB_TOKEN" -H "Accept: application/vnd.github.v3.raw+json" -X DELETE --data @- "https://api.github.com/repos/$GITHUB_REPOSITORY/contents/$path"
}
function git_upload_to_pages(){
local path=$1
local src=$2
if [ ! -f "$src" ]; then
>&2 echo "Input is not a file! Aborting..."
return 1
fi
local info=`curl -s -k -H "Authorization: token $GITHUB_TOKEN" -H "Accept: application/vnd.github.v3.object+json" -X GET "https://api.github.com/repos/$GITHUB_REPOSITORY/contents/$path?ref=gh-pages"`
local type=`echo "$info" | jq -r '.type'`
local message=$(basename $path)
local sha=""
local content=""
if [ $type == "file" ]; then
sha=`echo "$info" | jq -r '.sha'`
sha=",\"sha\":\"$sha\""
message="Updating $message"
elif [ ! $type == "null" ]; then
>&2 echo "Wrong type '$type'"
return 1
else
message="Creating $message"
fi
content=`base64 -i "$src"`
data="{\"branch\":\"gh-pages\",\"message\":\"$message\",\"content\":\"$content\"$sha}"
echo "$data" | curl -s -k -H "Authorization: token $GITHUB_TOKEN" -H "Accept: application/vnd.github.v3.raw+json" -X PUT --data @- "https://api.github.com/repos/$GITHUB_REPOSITORY/contents/$path"
}
function git_safe_upload_to_pages(){
local path=$1
local file="$2"
local name=$(basename "$file")
local size=`get_file_size "$file"`
local upload_res=`git_upload_to_pages "$path" "$file"`
if [ $? -ne 0 ]; then
>&2 echo "ERROR: Failed to upload '$name' ($?)"
return 1
fi
up_size=`echo "$upload_res" | jq -r '.content.size'`
if [ $up_size -ne $size ]; then
>&2 echo "ERROR: Uploaded size does not match! $up_size != $size"
#git_delete_asset
return 1
fi
echo "$upload_res" | jq -r '.content.download_url'
return $?
}
EVENT_JSON=`cat $GITHUB_EVENT_PATH`
pages_added=`echo "$EVENT_JSON" | jq -r '.commits[].added[]'`
pages_modified=`echo "$EVENT_JSON" | jq -r '.commits[].modified[]'`
pages_removed=`echo "$EVENT_JSON" | jq -r '.commits[].removed[]'`
for page in $pages_added; do
if [[ $page != "README.md" && $page != "docs/"* ]]; then
continue
fi
echo "Adding '$page' to pages ..."
if [[ $page == "README.md" ]]; then
git_safe_upload_to_pages "index.md" "README.md"
else
git_safe_upload_to_pages "$page" "$page"
fi
done
for page in $pages_modified; do
if [[ $page != "README.md" && $page != "docs/"* ]]; then
continue
fi
echo "Modifying '$page' ..."
if [[ $page == "README.md" ]]; then
git_safe_upload_to_pages "index.md" "README.md"
else
git_safe_upload_to_pages "$page" "$page"
fi
done
for page in $pages_removed; do
if [[ $page != "README.md" && $page != "docs/"* ]]; then
continue
fi
echo "Removing '$page' from pages ..."
if [[ $page == "README.md" ]]; then
git_remove_from_pages "README.md" > /dev/null
else
git_remove_from_pages "$page" > /dev/null
fi
done
echo
echo "DONE!"

View File

@ -1,5 +1,7 @@
#!/bin/bash
set -e
if [ ! -z "$TRAVIS_TAG" ]; then
echo "Skipping Test: Tagged build"
exit 0
@ -52,7 +54,6 @@ if [ "$BUILD_PIO" -eq 0 ]; then
# CMake Test
if [ "$CHUNK_INDEX" -eq 0 ]; then
bash "$ARDUINO_ESP32_PATH/.github/scripts/check-cmakelists.sh"
if [ $? -ne 0 ]; then exit 1; fi
fi
build_sketches "$FQBN" "$ARDUINO_ESP32_PATH/libraries" "$CHUNK_INDEX" "$CHUNKS_CNT"
fi
@ -68,4 +69,3 @@ else
build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino"
#build_pio_sketches esp32dev "$PLATFORMIO_ESP32_PATH/libraries"
fi
if [ $? -ne 0 ]; then exit 1; fi

21
.github/workflows/gh-pages.yml vendored Normal file
View File

@ -0,0 +1,21 @@
name: GitHub Pages CI
on:
push:
branches:
- master
paths:
- 'README.md'
- 'docs/**'
jobs:
build-pages:
name: Build GitHub Pages
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Copy Files
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: bash ./.github/scripts/on-pages.sh

View File

@ -173,19 +173,34 @@ esp32wrover.build.boot=dio
esp32wrover.build.partitions=default
esp32wrover.build.defines=-DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue
esp32wrover.menu.PartitionScheme.default=Default
esp32wrover.menu.PartitionScheme.default=Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS)
esp32wrover.menu.PartitionScheme.default.build.partitions=default
esp32wrover.menu.PartitionScheme.minimal=Minimal (2MB FLASH)
esp32wrover.menu.PartitionScheme.defaultffat=Default 4MB with ffat (1.2MB APP/1.5MB FATFS)
esp32wrover.menu.PartitionScheme.defaultffat.build.partitions=default_ffat
esp32wrover.menu.PartitionScheme.default_8MB=8M Flash (3MB APP/1.5MB FAT)
esp32wrover.menu.PartitionScheme.default_8MB.build.partitions=default_8MB
esp32wrover.menu.PartitionScheme.minimal=Minimal (1.3MB APP/700KB SPIFFS)
esp32wrover.menu.PartitionScheme.minimal.build.partitions=minimal
esp32wrover.menu.PartitionScheme.no_ota=No OTA (Large APP)
esp32wrover.menu.PartitionScheme.no_ota=No OTA (2MB APP/2MB SPIFFS)
esp32wrover.menu.PartitionScheme.no_ota.build.partitions=no_ota
esp32wrover.menu.PartitionScheme.no_ota.upload.maximum_size=2097152
esp32wrover.menu.PartitionScheme.huge_app=Huge APP (3MB No OTA)
esp32wrover.menu.PartitionScheme.noota_3g=No OTA (1MB APP/3MB SPIFFS)
esp32wrover.menu.PartitionScheme.noota_3g.build.partitions=noota_3g
esp32wrover.menu.PartitionScheme.noota_3g.upload.maximum_size=1048576
esp32wrover.menu.PartitionScheme.noota_ffat=No OTA (2MB APP/2MB FATFS)
esp32wrover.menu.PartitionScheme.noota_ffat.build.partitions=noota_ffat
esp32wrover.menu.PartitionScheme.noota_ffat.upload.maximum_size=2097152
esp32wrover.menu.PartitionScheme.noota_3gffat=No OTA (1MB APP/3MB FATFS)
esp32wrover.menu.PartitionScheme.noota_3gffat.build.partitions=noota_3gffat
esp32wrover.menu.PartitionScheme.noota_3gffat.upload.maximum_size=1048576
esp32wrover.menu.PartitionScheme.huge_app=Huge APP (3MB No OTA/1MB SPIFFS)
esp32wrover.menu.PartitionScheme.huge_app.build.partitions=huge_app
esp32wrover.menu.PartitionScheme.huge_app.upload.maximum_size=3145728
esp32wrover.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (Large APPS with OTA)
esp32wrover.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (1.9MB APP with OTA/190KB SPIFFS)
esp32wrover.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs
esp32wrover.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080
esp32wrover.menu.PartitionScheme.fatflash=16M Flash (2MB APP/12.5MB FAT)
esp32wrover.menu.PartitionScheme.fatflash.build.partitions=ffat
esp32wrover.menu.FlashMode.qio=QIO
esp32wrover.menu.FlashMode.qio.build.flash_mode=dio

View File

@ -31,11 +31,11 @@ extern "C" {
/**
* convert input data to base64
* @param data uint8_t *
* @param data const uint8_t *
* @param length size_t
* @return String
*/
String base64::encode(uint8_t * data, size_t length)
String base64::encode(const uint8_t * data, size_t length)
{
size_t size = base64_encode_expected_len(length) + 1;
char * buffer = (char *) malloc(size);
@ -54,10 +54,10 @@ String base64::encode(uint8_t * data, size_t length)
/**
* convert input data to base64
* @param text String
* @param text const String&
* @return String
*/
String base64::encode(String text)
String base64::encode(const String& text)
{
return base64::encode((uint8_t *) text.c_str(), text.length());
}

View File

@ -4,8 +4,8 @@
class base64
{
public:
static String encode(uint8_t * data, size_t length);
static String encode(String text);
static String encode(const uint8_t * data, size_t length);
static String encode(const String& text);
private:
};

View File

@ -10,4 +10,4 @@ Starting with 1.6.4, Arduino allows installation of third-party platform package
Stable release link: `https://dl.espressif.com/dl/package_esp32_index.json`
Development release link: `https://dl.espressif.com/dl/package_esp32_dev_index.json`
Development release link: `https://espressif.github.io/arduino-esp32/package_esp32_dev_index.json`

View File

@ -32,14 +32,8 @@
#include "esp32-hal-bt.h"
#endif
#if defined(CONFIG_ARDUHAL_ESP_LOG)
#include "esp32-hal-log.h"
#else
#include "esp_log.h"
static const char* LOG_TAG = "BLEDevice";
#endif
/**
* Singletons for the BLEDevice.

View File

@ -0,0 +1,56 @@
//This example code is in the Public Domain (or CC0 licensed, at your option.)
//By Victor Tchistiak - 2019
//
//This example demostrates master mode bluetooth connection and pin
//it creates a bridge between Serial and Classical Bluetooth (SPP)
//this is an extention of the SerialToSerialBT example by Evandro Copercini - 2018
//
#include "BluetoothSerial.h"
BluetoothSerial SerialBT;
String MACadd = "AA:BB:CC:11:22:33";
uint8_t address[6] = {0xAA, 0xBB, 0xCC, 0x11, 0x22, 0x33};
//uint8_t address[6] = {0x00, 0x1D, 0xA5, 0x02, 0xC3, 0x22};
String name = "OBDII";
char *pin = "1234"; //<- standard pin would be provided by default
bool connected;
void setup() {
Serial.begin(115200);
//SerialBT.setPin(pin);
SerialBT.begin("ESP32test", true);
//SerialBT.setPin(pin);
Serial.println("The device started in master mode, make sure remote BT device is on!");
// connect(address) is fast (upto 10 secs max), connect(name) is slow (upto 30 secs max) as it needs
// to resolve name to address first, but it allows to connect to different devices with the same name.
// Set CoreDebugLevel to Info to view devices bluetooth address and device names
connected = SerialBT.connect(name);
//connected = SerialBT.connect(address);
if(connected) {
Serial.println("Connected Succesfully!");
} else {
while(!SerialBT.connected(10000)) {
Serial.println("Failed to connect. Make sure remote device is available and in range, then restart app.");
}
}
// disconnect() may take upto 10 secs max
if (SerialBT.disconnect()) {
Serial.println("Disconnected Succesfully!");
}
// this would reconnect to the name(will use address, if resolved) or address used with connect(name/address).
SerialBT.connect();
}
void loop() {
if (Serial.available()) {
SerialBT.write(Serial.read());
}
if (SerialBT.available()) {
Serial.write(SerialBT.read());
}
delay(20);
}

View File

@ -0,0 +1,87 @@
//This example code is in the Public Domain (or CC0 licensed, at your option.)
//By Victor Tchistiak - 2019
//
//This example demonstrates reading and removing paired devices stored on the ESP32 flash memory
//Sometimes you may find your ESP32 device could not connect to the remote device despite
//many successful connections earlier. This is most likely a result of client replacing your paired
//device info with new one from other device. The BT clients store connection info for paired devices,
//but it is limited to a few devices only. When new device pairs and number of stored devices is exceeded,
//one of the previously paired devices would be replaced with new one.
//The only remedy is to delete this saved bound device from your device flash memory
//and pair with the other device again.
//
#include "esp_bt_main.h"
#include "esp_bt_device.h"
#include"esp_gap_bt_api.h"
#include "esp_err.h"
#define REMOVE_BONDED_DEVICES 0 // <- Set to 0 to view all bonded devices addresses, set to 1 to remove
#define PAIR_MAX_DEVICES 20
uint8_t pairedDeviceBtAddr[PAIR_MAX_DEVICES][6];
char bda_str[18];
bool initBluetooth()
{
if(!btStart()) {
Serial.println("Failed to initialize controller");
return false;
}
if(esp_bluedroid_init() != ESP_OK) {
Serial.println("Failed to initialize bluedroid");
return false;
}
if(esp_bluedroid_enable() != ESP_OK) {
Serial.println("Failed to enable bluedroid");
return false;
}
return true;
}
char *bda2str(const uint8_t* bda, char *str, size_t size)
{
if (bda == NULL || str == NULL || size < 18) {
return NULL;
}
sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x",
bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
return str;
}
void setup() {
Serial.begin(115200);
initBluetooth();
Serial.print("ESP32 bluetooth address: "); Serial.println(bda2str(esp_bt_dev_get_address(), bda_str, 18));
// Get the numbers of bonded/paired devices in the BT module
int count = esp_bt_gap_get_bond_device_num();
if(!count) {
Serial.println("No bonded device found.");
} else {
Serial.print("Bonded device count: "); Serial.println(count);
if(PAIR_MAX_DEVICES < count) {
count = PAIR_MAX_DEVICES;
Serial.print("Reset bonded device count: "); Serial.println(count);
}
esp_err_t tError = esp_bt_gap_get_bond_device_list(&count, pairedDeviceBtAddr);
if(ESP_OK == tError) {
for(int i = 0; i < count; i++) {
Serial.print("Found bonded device # "); Serial.print(i); Serial.print(" -> ");
Serial.println(bda2str(pairedDeviceBtAddr[i], bda_str, 18));
if(REMOVE_BONDED_DEVICES) {
esp_err_t tError = esp_bt_gap_remove_bond_device(pairedDeviceBtAddr[i]);
if(ESP_OK == tError) {
Serial.print("Removed bonded device # ");
} else {
Serial.print("Failed to remove bonded device # ");
}
Serial.println(i);
}
}
}
}
}
void loop() {}

356
libraries/BluetoothSerial/src/BluetoothSerial.cpp Normal file → Executable file
View File

@ -53,15 +53,80 @@ static EventGroupHandle_t _spp_event_group = NULL;
static boolean secondConnectionAttempt;
static esp_spp_cb_t * custom_spp_callback = NULL;
#define INQ_LEN 0x10
#define INQ_NUM_RSPS 20
#define READY_TIMEOUT (10 * 1000)
#define SCAN_TIMEOUT (INQ_LEN * 2 * 1000)
static esp_bd_addr_t _peer_bd_addr;
static char _remote_name[ESP_BT_GAP_MAX_BDNAME_LEN + 1];
static bool _isRemoteAddressSet;
static bool _isMaster;
static esp_bt_pin_code_t _pin_code;
static int _pin_len;
static bool _isPinSet;
static bool _enableSSP;
#define SPP_RUNNING 0x01
#define SPP_CONNECTED 0x02
#define SPP_CONGESTED 0x04
#define SPP_DISCONNECTED 0x08
typedef struct {
size_t len;
uint8_t data[];
} spp_packet_t;
static char *bda2str(esp_bd_addr_t bda, char *str, size_t size)
{
if (bda == NULL || str == NULL || size < 18) {
return NULL;
}
uint8_t *p = bda;
sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x",
p[0], p[1], p[2], p[3], p[4], p[5]);
return str;
}
static bool get_name_from_eir(uint8_t *eir, char *bdname, uint8_t *bdname_len)
{
if (!eir || !bdname || !bdname_len) {
return false;
}
uint8_t *rmt_bdname, rmt_bdname_len;
*bdname = *bdname_len = rmt_bdname_len = 0;
rmt_bdname = esp_bt_gap_resolve_eir_data(eir, ESP_BT_EIR_TYPE_CMPL_LOCAL_NAME, &rmt_bdname_len);
if (!rmt_bdname) {
rmt_bdname = esp_bt_gap_resolve_eir_data(eir, ESP_BT_EIR_TYPE_SHORT_LOCAL_NAME, &rmt_bdname_len);
}
if (rmt_bdname) {
rmt_bdname_len = rmt_bdname_len > ESP_BT_GAP_MAX_BDNAME_LEN ? ESP_BT_GAP_MAX_BDNAME_LEN : rmt_bdname_len;
memcpy(bdname, rmt_bdname, rmt_bdname_len);
bdname[rmt_bdname_len] = 0;
*bdname_len = rmt_bdname_len;
return true;
}
return false;
}
static bool btSetPin() {
esp_bt_pin_type_t pin_type;
if (_isPinSet) {
if (_pin_len) {
log_i("pin set");
pin_type = ESP_BT_PIN_TYPE_FIXED;
} else {
_isPinSet = false;
log_i("pin reset");
pin_type = ESP_BT_PIN_TYPE_VARIABLE; // pin_code would be ignored (default)
}
return (esp_bt_gap_set_pin(pin_type, _pin_len, _pin_code) == ESP_OK);
}
return false;
}
static esp_err_t _spp_queue_packet(uint8_t *data, size_t len){
if(!data || !len){
log_w("No data provided");
@ -159,29 +224,34 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
case ESP_SPP_INIT_EVT:
log_i("ESP_SPP_INIT_EVT");
esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE);
esp_spp_start_srv(ESP_SPP_SEC_NONE, ESP_SPP_ROLE_SLAVE, 0, _spp_server_name);
if (!_isMaster) {
log_i("ESP_SPP_INIT_EVT: slave: start");
esp_spp_start_srv(ESP_SPP_SEC_NONE, ESP_SPP_ROLE_SLAVE, 0, _spp_server_name);
}
xEventGroupSetBits(_spp_event_group, SPP_RUNNING);
break;
case ESP_SPP_SRV_OPEN_EVT://Server connection open
log_i("ESP_SPP_SRV_OPEN_EVT");
if (!_spp_client){
_spp_client = param->open.handle;
} else {
secondConnectionAttempt = true;
esp_spp_disconnect(param->open.handle);
}
xEventGroupClearBits(_spp_event_group, SPP_DISCONNECTED);
xEventGroupSetBits(_spp_event_group, SPP_CONNECTED);
log_i("ESP_SPP_SRV_OPEN_EVT");
break;
case ESP_SPP_CLOSE_EVT://Client connection closed
log_i("ESP_SPP_CLOSE_EVT");
if(secondConnectionAttempt) {
secondConnectionAttempt = false;
} else {
_spp_client = 0;
}
xEventGroupSetBits(_spp_event_group, SPP_DISCONNECTED);
}
xEventGroupClearBits(_spp_event_group, SPP_CONNECTED);
log_i("ESP_SPP_CLOSE_EVT");
break;
case ESP_SPP_CONG_EVT://connection congestion status changed
@ -216,25 +286,149 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
}
break;
//should maybe delete those.
case ESP_SPP_DISCOVERY_COMP_EVT://discovery complete
log_i("ESP_SPP_DISCOVERY_COMP_EVT");
if (param->disc_comp.status == ESP_SPP_SUCCESS) {
log_i("ESP_SPP_DISCOVERY_COMP_EVT: spp connect to remote");
esp_spp_connect(ESP_SPP_SEC_AUTHENTICATE, ESP_SPP_ROLE_MASTER, param->disc_comp.scn[0], _peer_bd_addr);
}
break;
case ESP_SPP_OPEN_EVT://Client connection open
log_i("ESP_SPP_OPEN_EVT");
if (!_spp_client){
_spp_client = param->open.handle;
} else {
secondConnectionAttempt = true;
esp_spp_disconnect(param->open.handle);
}
xEventGroupClearBits(_spp_event_group, SPP_DISCONNECTED);
xEventGroupSetBits(_spp_event_group, SPP_CONNECTED);
break;
case ESP_SPP_START_EVT://server started
log_i("ESP_SPP_START_EVT");
break;
case ESP_SPP_CL_INIT_EVT://client initiated a connection
log_i("ESP_SPP_CL_INIT_EVT");
break;
default:
break;
}
if(custom_spp_callback)(*custom_spp_callback)(event, param);
}
static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param)
{
switch(event){
case ESP_BT_GAP_DISC_RES_EVT:
log_i("ESP_BT_GAP_DISC_RES_EVT");
char bda_str[18];
log_i("Scanned device: %s", bda2str(param->disc_res.bda, bda_str, 18));
for (int i = 0; i < param->disc_res.num_prop; i++) {
uint8_t peer_bdname_len;
char peer_bdname[ESP_BT_GAP_MAX_BDNAME_LEN + 1];
switch(param->disc_res.prop[i].type) {
case ESP_BT_GAP_DEV_PROP_EIR:
if (get_name_from_eir((uint8_t*)param->disc_res.prop[i].val, peer_bdname, &peer_bdname_len)) {
log_i("ESP_BT_GAP_DISC_RES_EVT : EIR : %s : %d", peer_bdname, peer_bdname_len);
if (strlen(_remote_name) == peer_bdname_len
&& strncmp(peer_bdname, _remote_name, peer_bdname_len) == 0) {
log_v("ESP_BT_GAP_DISC_RES_EVT : SPP_START_DISCOVERY_EIR : %s", peer_bdname, peer_bdname_len);
_isRemoteAddressSet = true;
memcpy(_peer_bd_addr, param->disc_res.bda, ESP_BD_ADDR_LEN);
esp_bt_gap_cancel_discovery();
esp_spp_start_discovery(_peer_bd_addr);
}
}
break;
case ESP_BT_GAP_DEV_PROP_BDNAME:
peer_bdname_len = param->disc_res.prop[i].len;
memcpy(peer_bdname, param->disc_res.prop[i].val, peer_bdname_len);
peer_bdname_len--; // len includes 0 terminator
log_v("ESP_BT_GAP_DISC_RES_EVT : BDNAME : %s : %d", peer_bdname, peer_bdname_len);
if (strlen(_remote_name) == peer_bdname_len
&& strncmp(peer_bdname, _remote_name, peer_bdname_len) == 0) {
log_i("ESP_BT_GAP_DISC_RES_EVT : SPP_START_DISCOVERY_BDNAME : %s", peer_bdname);
_isRemoteAddressSet = true;
memcpy(_peer_bd_addr, param->disc_res.bda, ESP_BD_ADDR_LEN);
esp_bt_gap_cancel_discovery();
esp_spp_start_discovery(_peer_bd_addr);
}
break;
case ESP_BT_GAP_DEV_PROP_COD:
//log_i("ESP_BT_GAP_DEV_PROP_COD");
break;
case ESP_BT_GAP_DEV_PROP_RSSI:
//log_i("ESP_BT_GAP_DEV_PROP_RSSI");
break;
default:
break;
}
if (_isRemoteAddressSet)
break;
}
break;
case ESP_BT_GAP_DISC_STATE_CHANGED_EVT:
log_i("ESP_BT_GAP_DISC_STATE_CHANGED_EVT");
break;
case ESP_BT_GAP_RMT_SRVCS_EVT:
log_i( "ESP_BT_GAP_RMT_SRVCS_EVT");
break;
case ESP_BT_GAP_RMT_SRVC_REC_EVT:
log_i("ESP_BT_GAP_RMT_SRVC_REC_EVT");
break;
case ESP_BT_GAP_AUTH_CMPL_EVT:
if (param->auth_cmpl.stat == ESP_BT_STATUS_SUCCESS) {
log_v("authentication success: %s", param->auth_cmpl.device_name);
} else {
log_e("authentication failed, status:%d", param->auth_cmpl.stat);
}
break;
case ESP_BT_GAP_PIN_REQ_EVT:
// default pairing pins
log_i("ESP_BT_GAP_PIN_REQ_EVT min_16_digit:%d", param->pin_req.min_16_digit);
if (param->pin_req.min_16_digit) {
log_i("Input pin code: 0000 0000 0000 0000");
esp_bt_pin_code_t pin_code;
memset(pin_code, '0', ESP_BT_PIN_CODE_LEN);
esp_bt_gap_pin_reply(param->pin_req.bda, true, 16, pin_code);
} else {
log_i("Input pin code: 1234");
esp_bt_pin_code_t pin_code;
memcpy(pin_code, "1234", 4);
esp_bt_gap_pin_reply(param->pin_req.bda, true, 4, pin_code);
}
break;
case ESP_BT_GAP_CFM_REQ_EVT:
log_i("ESP_BT_GAP_CFM_REQ_EVT Please compare the numeric value: %d", param->cfm_req.num_val);
esp_bt_gap_ssp_confirm_reply(param->cfm_req.bda, true);
break;
case ESP_BT_GAP_KEY_NOTIF_EVT:
log_i("ESP_BT_GAP_KEY_NOTIF_EVT passkey:%d", param->key_notif.passkey);
break;
case ESP_BT_GAP_KEY_REQ_EVT:
log_i("ESP_BT_GAP_KEY_REQ_EVT Please enter passkey!");
break;
default:
break;
}
}
static bool _init_bt(const char *deviceName)
{
if(!_spp_event_group){
@ -245,6 +439,7 @@ static bool _init_bt(const char *deviceName)
}
xEventGroupClearBits(_spp_event_group, 0xFFFFFF);
xEventGroupSetBits(_spp_event_group, SPP_CONGESTED);
xEventGroupSetBits(_spp_event_group, SPP_DISCONNECTED);
}
if (_spp_rx_queue == NULL){
_spp_rx_queue = xQueueCreate(RX_QUEUE_SIZE, sizeof(uint8_t)); //initialize the queue
@ -297,6 +492,11 @@ static bool _init_bt(const char *deviceName)
}
}
if (_isMaster && esp_bt_gap_register_callback(esp_bt_gap_cb) != ESP_OK) {
log_e("gap register failed");
return false;
}
if (esp_spp_register_callback(esp_spp_cb) != ESP_OK){
log_e("spp register failed");
return false;
@ -307,8 +507,20 @@ static bool _init_bt(const char *deviceName)
return false;
}
log_i("device name set");
esp_bt_dev_set_device_name(deviceName);
if (_isPinSet) {
btSetPin();
}
if (_enableSSP) {
log_i("Simple Secure Pairing");
esp_bt_sp_param_t param_type = ESP_BT_SP_IOCAP_MODE;
esp_bt_io_cap_t iocap = ESP_BT_IO_CAP_IO;
esp_bt_gap_set_security_param(param_type, &iocap, sizeof(uint8_t));
}
// the default BTA_DM_COD_LOUDSPEAKER does not work with the macOS BT stack
esp_bt_cod_t cod;
cod.major = 0b00001;
@ -318,7 +530,6 @@ static bool _init_bt(const char *deviceName)
log_e("set cod failed");
return false;
}
return true;
}
@ -361,6 +572,11 @@ static bool _stop_bt()
return true;
}
static bool waitForConnect(int timeout) {
TickType_t xTicksToWait = timeout / portTICK_PERIOD_MS;
return (xEventGroupWaitBits(_spp_event_group, SPP_CONNECTED, pdFALSE, pdTRUE, xTicksToWait) != 0);
}
/*
* Serial Bluetooth Arduino
*
@ -376,8 +592,9 @@ BluetoothSerial::~BluetoothSerial(void)
_stop_bt();
}
bool BluetoothSerial::begin(String localName)
bool BluetoothSerial::begin(String localName, bool isMaster)
{
_isMaster = isMaster;
if (localName.length()){
local_name = localName;
}
@ -445,4 +662,129 @@ esp_err_t BluetoothSerial::register_callback(esp_spp_cb_t * callback)
return ESP_OK;
}
//Simple Secure Pairing
void BluetoothSerial::enableSSP() {
_enableSSP = true;
}
/*
* Set default parameters for Legacy Pairing
* Use fixed pin code
*/
bool BluetoothSerial::setPin(const char *pin) {
bool isEmpty = !(pin && *pin);
if (isEmpty && !_isPinSet) {
return true; // nothing to do
} else if (!isEmpty){
_pin_len = strlen(pin);
memcpy(_pin_code, pin, _pin_len);
} else {
_pin_len = 0; // resetting pin to none (default)
}
_pin_code[_pin_len] = 0;
_isPinSet = true;
if (isReady(false, READY_TIMEOUT)) {
btSetPin();
}
return true;
}
bool BluetoothSerial::connect(String remoteName)
{
if (!isReady(true, READY_TIMEOUT)) return false;
if (remoteName && remoteName.length() < 1) {
log_e("No remote name is provided");
return false;
}
disconnect();
_isRemoteAddressSet = false;
strncpy(_remote_name, remoteName.c_str(), ESP_BT_GAP_MAX_BDNAME_LEN);
_remote_name[ESP_BT_GAP_MAX_BDNAME_LEN] = 0;
log_i("master : remoteName");
// will first resolve name to address
esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE);
if (esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, INQ_LEN, INQ_NUM_RSPS) == ESP_OK) {
return waitForConnect(SCAN_TIMEOUT);
}
return false;
}
bool BluetoothSerial::connect(uint8_t remoteAddress[])
{
if (!isReady(true, READY_TIMEOUT)) return false;
if (!remoteAddress) {
log_e("No remote address is provided");
return false;
}
disconnect();
_remote_name[0] = 0;
_isRemoteAddressSet = true;
memcpy(_peer_bd_addr, remoteAddress, ESP_BD_ADDR_LEN);
log_i("master : remoteAddress");
if (esp_spp_start_discovery(_peer_bd_addr) == ESP_OK) {
return waitForConnect(READY_TIMEOUT);
}
return false;
}
bool BluetoothSerial::connect()
{
if (!isReady(true, READY_TIMEOUT)) return false;
if (_isRemoteAddressSet){
disconnect();
// use resolved or set address first
log_i("master : remoteAddress");
if (esp_spp_start_discovery(_peer_bd_addr) == ESP_OK) {
return waitForConnect(READY_TIMEOUT);
}
return false;
} else if (_remote_name[0]) {
disconnect();
log_i("master : remoteName");
// will resolve name to address first - it may take a while
esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE);
if (esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, INQ_LEN, INQ_NUM_RSPS) == ESP_OK) {
return waitForConnect(SCAN_TIMEOUT);
}
return false;
}
log_e("Neither Remote name nor address was provided");
return false;
}
bool BluetoothSerial::disconnect() {
if (_spp_client) {
flush();
log_i("disconnecting");
if (esp_spp_disconnect(_spp_client) == ESP_OK) {
TickType_t xTicksToWait = READY_TIMEOUT / portTICK_PERIOD_MS;
return (xEventGroupWaitBits(_spp_event_group, SPP_DISCONNECTED, pdFALSE, pdTRUE, xTicksToWait) != 0);
}
}
return false;
}
bool BluetoothSerial::unpairDevice(uint8_t remoteAddress[]) {
if (isReady(false, READY_TIMEOUT)) {
log_i("removing bonded device");
return (esp_bt_gap_remove_bond_device(remoteAddress) == ESP_OK);
}
return false;
}
bool BluetoothSerial::connected(int timeout) {
return waitForConnect(timeout);
}
bool BluetoothSerial::isReady(bool checkMaster, int timeout) {
if (checkMaster && !_isMaster) {
log_e("Master mode is not active. Call begin(localName, true) to enable Master mode");
return false;
}
if (!btStarted()) {
log_e("BT is not initialized. Call begin() first");
return false;
}
TickType_t xTicksToWait = timeout / portTICK_PERIOD_MS;
return (xEventGroupWaitBits(_spp_event_group, SPP_RUNNING, pdFALSE, pdTRUE, xTicksToWait) != 0);
}
#endif

12
libraries/BluetoothSerial/src/BluetoothSerial.h Normal file → Executable file
View File

@ -30,7 +30,7 @@ class BluetoothSerial: public Stream
BluetoothSerial(void);
~BluetoothSerial(void);
bool begin(String localName=String());
bool begin(String localName=String(), bool isMaster=false);
int available(void);
int peek(void);
bool hasClient(void);
@ -41,6 +41,16 @@ class BluetoothSerial: public Stream
void end(void);
esp_err_t register_callback(esp_spp_cb_t * callback);
void enableSSP();
bool setPin(const char *pin);
bool connect(String remoteName);
bool connect(uint8_t remoteAddress[]);
bool connect();
bool connected(int timeout=0);
bool isReady(bool checkMaster=false, int timeout=0);
bool disconnect();
bool unpairDevice(uint8_t remoteAddress[]);
private:
String local_name;

View File

@ -36,8 +36,10 @@ void setup()
void loop()
{
const uint16_t port = 80;
const char * host = "192.168.1.1"; // ip or dns
// const uint16_t port = 80;
// const char * host = "192.168.1.1"; // ip or dns
const uint16_t port = 1337;
const char * host = "192.168.1.10"; // ip or dns
Serial.print("Connecting to ");
Serial.println(host);
@ -53,11 +55,29 @@ void loop()
}
// This will send a request to the server
client.print("Send this data to the server");
//uncomment this line to send an arbitrary string to the server
//client.print("Send this data to the server");
//uncomment this line to send a basic document request to the server
client.print("GET /index.html HTTP/1.1\n\n");
int maxloops = 0;
//wait for the server's reply to become available
while (!client.available() && maxloops < 1000)
{
maxloops++;
delay(1); //delay 1 msec
}
if (client.available() > 0)
{
//read back one line from the server
String line = client.readStringUntil('\r');
client.println(line);
Serial.println(line);
}
else
{
Serial.println("client.available() timed out ");
}
Serial.println("Closing connection.");
client.stop();
@ -65,4 +85,3 @@ void loop()
Serial.println("Waiting 5 seconds before restarting...");
delay(5000);
}

View File

@ -83,6 +83,13 @@
"archiveFileName": "xtensa-esp32-elf-linux32-1.22.0-80-g6c4433a-5.2.0.tar.gz",
"checksum": "SHA-256:b4055695ffc2dfc0bcb6dafdc2572a6e01151c4179ef5fa972b3fcb2183eb155",
"size": "45566336"
},
{
"host": "arm-linux-gnueabihf",
"url": "https://dl.espressif.com/dl/xtensa-esp32-elf-linux-armel-1.22.0-87-gb57bad3-5.2.0.tar.gz",
"archiveFileName": "xtensa-esp32-elf-linux-armel-1.22.0-87-gb57bad3-5.2.0.tar.gz",
"checksum": "SHA-256:9c68c87bb23b1256dc0a1859b515946763e5292dcab4a4159a52fae5618ce861",
"size": "50655584"
}
]
},

View File

@ -60,7 +60,7 @@ def report_progress(count, blockSize, totalSize):
def unpack(filename, destination):
dirname = ''
print('Extracting {0}'.format(os.path.basename(filename)))
print('Extracting {0} ...'.format(os.path.basename(filename)))
sys.stdout.flush()
if filename.endswith('tar.gz'):
tfile = tarfile.open(filename, 'r:gz')
@ -76,7 +76,7 @@ def unpack(filename, destination):
# a little trick to rename tool directories so they don't contain version number
rename_to = re.match(r'^([a-z][^\-]*\-*)+', dirname).group(0).strip('-')
if rename_to != dirname:
print('Renaming {0} to {1}'.format(dirname, rename_to))
print('Renaming {0} to {1} ...'.format(dirname, rename_to))
if os.path.isdir(rename_to):
shutil.rmtree(rename_to)
shutil.move(dirname, rename_to)
@ -106,9 +106,8 @@ def get_tool(tool):
archive_name = tool['archiveFileName']
local_path = dist_dir + archive_name
url = tool['url']
#real_hash = tool['checksum'].split(':')[1]
if not os.path.isfile(local_path):
print('Downloading ' + archive_name)
print('Downloading ' + archive_name + ' ...')
sys.stdout.flush()
if 'CYGWIN_NT' in sys_name:
import ssl
@ -122,20 +121,16 @@ def get_tool(tool):
f.write(r.content)
f.close()
else:
is_ci = os.environ.get('TRAVIS_BUILD_DIR');
is_ci = os.environ.get('GITHUB_WORKSPACE');
if is_ci:
download_file(url, local_path)
else:
urlretrieve(url, local_path, report_progress)
sys.stdout.write("\rDone\n")
sys.stdout.flush()
sys.stdout.write("\rDone\n")
sys.stdout.flush()
else:
print('Tool {0} already downloaded'.format(archive_name))
sys.stdout.flush()
#local_hash = sha256sum(local_path)
#if local_hash != real_hash:
# print('Hash mismatch for {0}, delete the file and try again'.format(local_path))
# raise RuntimeError()
unpack(local_path, '.')
def load_tools_list(filename, platform):
@ -158,11 +153,11 @@ def identify_platform():
bits = 64
sys_name = platform.system()
sys_platform = platform.platform()
print('System: %s, Info: %s' % (sys_name, sys_platform))
if 'Linux' in sys_name and sys_platform.find('arm') > 0:
if 'Linux' in sys_name and (sys_platform.find('arm') > 0 or sys_platform.find('aarch64') > 0):
sys_name = 'LinuxARM'
if 'CYGWIN_NT' in sys_name:
sys_name = 'Windows'
print('System: %s, Bits: %d, Info: %s' % (sys_name, bits, sys_platform))
return arduino_platform_names[sys_name][bits]
if __name__ == '__main__':
@ -172,4 +167,4 @@ if __name__ == '__main__':
mkdir_p(dist_dir)
for tool in tools_to_download:
get_tool(tool)
print('Done')
print('Platform Tools Installed')