Upload code
This commit is contained in:
		
							
								
								
									
										3
									
								
								src/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					build/
 | 
				
			||||||
 | 
					sdkconfig
 | 
				
			||||||
 | 
					sdkconfig.old
 | 
				
			||||||
							
								
								
									
										6
									
								
								src/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								src/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					# The following lines of boilerplate have to be in your project's
 | 
				
			||||||
 | 
					# CMakeLists in this exact order for cmake to work correctly
 | 
				
			||||||
 | 
					cmake_minimum_required(VERSION 3.5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include($ENV{IDF_PATH}/tools/cmake/project.cmake)
 | 
				
			||||||
 | 
					project(app-template)
 | 
				
			||||||
							
								
								
									
										9
									
								
								src/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/Makefile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					#
 | 
				
			||||||
 | 
					# This is a project Makefile. It is assumed the directory this Makefile resides in is a
 | 
				
			||||||
 | 
					# project subdirectory.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PROJECT_NAME := app-template
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include $(IDF_PATH)/make/project.mk
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										16
									
								
								src/components/GPIO_drv/.cproject
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/components/GPIO_drv/.cproject
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
				
			||||||
 | 
					<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
 | 
				
			||||||
 | 
						<storageModule moduleId="org.eclipse.cdt.core.settings">
 | 
				
			||||||
 | 
							<cconfiguration id="org.eclipse.cdt.core.default.config.818362570">
 | 
				
			||||||
 | 
								<storageModule buildSystemId="org.eclipse.cdt.core.defaultConfigDataProvider" id="org.eclipse.cdt.core.default.config.818362570" moduleId="org.eclipse.cdt.core.settings" name="Configuration">
 | 
				
			||||||
 | 
									<externalSettings/>
 | 
				
			||||||
 | 
									<extensions/>
 | 
				
			||||||
 | 
								</storageModule>
 | 
				
			||||||
 | 
								<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
 | 
				
			||||||
 | 
							</cconfiguration>
 | 
				
			||||||
 | 
						</storageModule>
 | 
				
			||||||
 | 
						<storageModule moduleId="org.eclipse.cdt.core.pathentry">
 | 
				
			||||||
 | 
							<pathentry excluding="**/CMakeFiles/**" kind="out" path="build"/>
 | 
				
			||||||
 | 
						</storageModule>
 | 
				
			||||||
 | 
						<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
 | 
				
			||||||
 | 
					</cproject>
 | 
				
			||||||
							
								
								
									
										20
									
								
								src/components/GPIO_drv/.project
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/components/GPIO_drv/.project
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="UTF-8"?>
 | 
				
			||||||
 | 
					<projectDescription>
 | 
				
			||||||
 | 
						<name>GPIO_drv</name>
 | 
				
			||||||
 | 
						<comment></comment>
 | 
				
			||||||
 | 
						<projects>
 | 
				
			||||||
 | 
						</projects>
 | 
				
			||||||
 | 
						<buildSpec>
 | 
				
			||||||
 | 
							<buildCommand>
 | 
				
			||||||
 | 
								<name>org.eclipse.cdt.core.cBuilder</name>
 | 
				
			||||||
 | 
								<triggers>clean,full,incremental,</triggers>
 | 
				
			||||||
 | 
								<arguments>
 | 
				
			||||||
 | 
								</arguments>
 | 
				
			||||||
 | 
							</buildCommand>
 | 
				
			||||||
 | 
						</buildSpec>
 | 
				
			||||||
 | 
						<natures>
 | 
				
			||||||
 | 
							<nature>org.eclipse.cdt.core.cnature</nature>
 | 
				
			||||||
 | 
							<nature>org.eclipse.cdt.core.ccnature</nature>
 | 
				
			||||||
 | 
							<nature>org.eclipse.cdt.cmake.core.cmakeNature</nature>
 | 
				
			||||||
 | 
						</natures>
 | 
				
			||||||
 | 
					</projectDescription>
 | 
				
			||||||
							
								
								
									
										3
									
								
								src/components/GPIO_drv/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/components/GPIO_drv/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					idf_component_register(SRCS "GPIO_drv.cpp"
 | 
				
			||||||
 | 
					                       INCLUDE_DIRS "."
 | 
				
			||||||
 | 
					                      )
 | 
				
			||||||
							
								
								
									
										48
									
								
								src/components/GPIO_drv/GPIO_drv.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								src/components/GPIO_drv/GPIO_drv.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,48 @@
 | 
				
			|||||||
 | 
					#include "GPIO_drv.hpp"
 | 
				
			||||||
 | 
					#include <algorithm>
 | 
				
			||||||
 | 
					#include "esp_log.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool GPIO_drv::isr_service_installed = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GPIO_drv::GPIO_drv()
 | 
				
			||||||
 | 
					    : clbk_ptr(nullptr) 
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GPIO_drv::~GPIO_drv()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void GPIO_drv::init(gpio_num_t but, gpio_mode_t mode, gpio_pullup_t pu, gpio_pulldown_t pd)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    button = but;
 | 
				
			||||||
 | 
					    gpio_config_t io_conf;
 | 
				
			||||||
 | 
					    io_conf.intr_type = GPIO_INTR_DISABLE;
 | 
				
			||||||
 | 
					    io_conf.mode = mode;
 | 
				
			||||||
 | 
					    io_conf.pin_bit_mask = (1ULL << button);
 | 
				
			||||||
 | 
					    io_conf.pull_down_en = pd;
 | 
				
			||||||
 | 
					    io_conf.pull_up_en = pu;
 | 
				
			||||||
 | 
					    gpio_config(&io_conf);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void GPIO_drv::enableINT(gpio_int_type_t type, Callback ptr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    gpio_set_intr_type(button, type);
 | 
				
			||||||
 | 
					    if (!isr_service_installed) 
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        gpio_install_isr_service(0);
 | 
				
			||||||
 | 
					        isr_service_installed = true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    gpio_isr_handler_add(button, ptr, (void*)button);
 | 
				
			||||||
 | 
					    gpio_intr_enable(button);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void GPIO_drv::setLvl(Lvl lvl)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    gpio_set_level(button, static_cast<std::uint32_t>(lvl));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Lvl GPIO_drv::getLvl()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return static_cast<Lvl>(gpio_get_level(button));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										32
									
								
								src/components/GPIO_drv/GPIO_drv.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								src/components/GPIO_drv/GPIO_drv.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
				
			|||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					#include <cstdint>
 | 
				
			||||||
 | 
					#include "driver/gpio.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using Callback = void(*)(void *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum class Lvl {reset, set};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class GPIO_drv
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    GPIO_drv();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    virtual ~GPIO_drv();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void     init(gpio_num_t but,
 | 
				
			||||||
 | 
					                  gpio_mode_t mode, 
 | 
				
			||||||
 | 
					                  gpio_pullup_t pu = GPIO_PULLUP_DISABLE, 
 | 
				
			||||||
 | 
					                  gpio_pulldown_t pd = GPIO_PULLDOWN_DISABLE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void     enableINT(gpio_int_type_t type, Callback ptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void     setLvl(Lvl lvl);
 | 
				
			||||||
 | 
					    Lvl      getLvl();
 | 
				
			||||||
 | 
					    inline gpio_num_t getGpioNum(void) {return button;}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    gpio_num_t button;
 | 
				
			||||||
 | 
					    Callback clbk_ptr;
 | 
				
			||||||
 | 
					    static bool isr_service_installed;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										16
									
								
								src/components/SPI_drv/.cproject
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/components/SPI_drv/.cproject
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
				
			||||||
 | 
					<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
 | 
				
			||||||
 | 
						<storageModule moduleId="org.eclipse.cdt.core.settings">
 | 
				
			||||||
 | 
							<cconfiguration id="org.eclipse.cdt.core.default.config.818362570">
 | 
				
			||||||
 | 
								<storageModule buildSystemId="org.eclipse.cdt.core.defaultConfigDataProvider" id="org.eclipse.cdt.core.default.config.818362570" moduleId="org.eclipse.cdt.core.settings" name="Configuration">
 | 
				
			||||||
 | 
									<externalSettings/>
 | 
				
			||||||
 | 
									<extensions/>
 | 
				
			||||||
 | 
								</storageModule>
 | 
				
			||||||
 | 
								<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
 | 
				
			||||||
 | 
							</cconfiguration>
 | 
				
			||||||
 | 
						</storageModule>
 | 
				
			||||||
 | 
						<storageModule moduleId="org.eclipse.cdt.core.pathentry">
 | 
				
			||||||
 | 
							<pathentry excluding="**/CMakeFiles/**" kind="out" path="build"/>
 | 
				
			||||||
 | 
						</storageModule>
 | 
				
			||||||
 | 
						<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
 | 
				
			||||||
 | 
					</cproject>
 | 
				
			||||||
							
								
								
									
										20
									
								
								src/components/SPI_drv/.project
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/components/SPI_drv/.project
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="UTF-8"?>
 | 
				
			||||||
 | 
					<projectDescription>
 | 
				
			||||||
 | 
						<name>SPI_drv</name>
 | 
				
			||||||
 | 
						<comment></comment>
 | 
				
			||||||
 | 
						<projects>
 | 
				
			||||||
 | 
						</projects>
 | 
				
			||||||
 | 
						<buildSpec>
 | 
				
			||||||
 | 
							<buildCommand>
 | 
				
			||||||
 | 
								<name>org.eclipse.cdt.core.cBuilder</name>
 | 
				
			||||||
 | 
								<triggers>clean,full,incremental,</triggers>
 | 
				
			||||||
 | 
								<arguments>
 | 
				
			||||||
 | 
								</arguments>
 | 
				
			||||||
 | 
							</buildCommand>
 | 
				
			||||||
 | 
						</buildSpec>
 | 
				
			||||||
 | 
						<natures>
 | 
				
			||||||
 | 
							<nature>org.eclipse.cdt.core.cnature</nature>
 | 
				
			||||||
 | 
							<nature>org.eclipse.cdt.core.ccnature</nature>
 | 
				
			||||||
 | 
							<nature>org.eclipse.cdt.cmake.core.cmakeNature</nature>
 | 
				
			||||||
 | 
						</natures>
 | 
				
			||||||
 | 
					</projectDescription>
 | 
				
			||||||
							
								
								
									
										4
									
								
								src/components/SPI_drv/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								src/components/SPI_drv/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					idf_component_register(SRCS "SPI_drv.cpp"
 | 
				
			||||||
 | 
					                       INCLUDE_DIRS "."
 | 
				
			||||||
 | 
					                       REQUIRES log
 | 
				
			||||||
 | 
					                      )
 | 
				
			||||||
							
								
								
									
										147
									
								
								src/components/SPI_drv/SPI_drv.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								src/components/SPI_drv/SPI_drv.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,147 @@
 | 
				
			|||||||
 | 
					#include "SPI_drv.hpp"
 | 
				
			||||||
 | 
					#include <esp_log.h>
 | 
				
			||||||
 | 
					#include <cstring>
 | 
				
			||||||
 | 
					//#include <algorithm>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//#define DEBUG 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    static constexpr char LOG_TAG[] = "SPI";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SPI_drv::SPI_drv() 
 | 
				
			||||||
 | 
					    : m_handle(nullptr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SPI_drv::init(spi_host_device_t host, int freq, gpio_num_t cs_pin, bool useMiso, uint8_t spiMode, uint32_t flags)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int misoPin;
 | 
				
			||||||
 | 
					    if (useMiso) misoPin = (host == VSPI_HOST) ? 19 : 12;
 | 
				
			||||||
 | 
					    else misoPin = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    spi_bus_config_t bus_config = {};
 | 
				
			||||||
 | 
						bus_config.sclk_io_num     = (host == VSPI_HOST) ? 18 : 14;  // CLK
 | 
				
			||||||
 | 
						bus_config.mosi_io_num     = (host == VSPI_HOST) ? 23 : 13; // MOSI
 | 
				
			||||||
 | 
						bus_config.miso_io_num     = misoPin; // MISO
 | 
				
			||||||
 | 
						bus_config.quadwp_io_num   = -1;      // Not used
 | 
				
			||||||
 | 
						bus_config.quadhd_io_num   = -1;      // Not used
 | 
				
			||||||
 | 
					    bus_config.flags           = (SPICOMMON_BUSFLAG_SCLK | SPICOMMON_BUSFLAG_MOSI);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						esp_err_t errRc = spi_bus_initialize(
 | 
				
			||||||
 | 
								host,
 | 
				
			||||||
 | 
								&bus_config,
 | 
				
			||||||
 | 
								host // DMA Channel
 | 
				
			||||||
 | 
						);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (errRc != ESP_OK) {
 | 
				
			||||||
 | 
							ESP_LOGE(LOG_TAG, "spi_bus_initialize(): rc=%d", errRc);
 | 
				
			||||||
 | 
							abort();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spi_device_interface_config_t dev_config = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						dev_config.clock_speed_hz   = freq;
 | 
				
			||||||
 | 
						dev_config.spics_io_num     = cs_pin;
 | 
				
			||||||
 | 
						dev_config.flags            |= SPI_DEVICE_NO_DUMMY;
 | 
				
			||||||
 | 
						dev_config.queue_size       = 1;
 | 
				
			||||||
 | 
						/*добавляем фазу передачи команды длиной 8 бит */
 | 
				
			||||||
 | 
						//dev_config.command_bits     = 8;
 | 
				
			||||||
 | 
						//dev_config.input_delay_ns   = 10;
 | 
				
			||||||
 | 
						dev_config.mode             = spiMode; //SPI mode, representing a pair of (CPOL, CPHA) configuration: 3 - (1, 1)
 | 
				
			||||||
 | 
														 //																2 - (1, 0)
 | 
				
			||||||
 | 
						dev_config.cs_ena_pretrans  = 0;
 | 
				
			||||||
 | 
						dev_config.cs_ena_posttrans = 0;
 | 
				
			||||||
 | 
						dev_config.duty_cycle_pos   = 128;
 | 
				
			||||||
 | 
						//dev_config.flags           |= (SPI_DEVICE_BIT_LSBFIRST);
 | 
				
			||||||
 | 
						dev_config.flags            |= flags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//ESP_LOGI(LOG_TAG, "... Adding device bus.");
 | 
				
			||||||
 | 
						errRc = ::spi_bus_add_device(host, &dev_config, &m_handle);
 | 
				
			||||||
 | 
						if (errRc != ESP_OK) {
 | 
				
			||||||
 | 
							ESP_LOGE(LOG_TAG, "spi_bus_add_device(): rc=%d", errRc);
 | 
				
			||||||
 | 
							abort();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SPI_drv::receive(std::uint8_t* rx_data, size_t dataLen)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// spi_transaction_t t = {
 | 
				
			||||||
 | 
					    //     .cmd = CMD_READ | (addr & ADDR_MASK),
 | 
				
			||||||
 | 
					    //     .rxlength = 8,
 | 
				
			||||||
 | 
					    //     .flags = SPI_TRANS_USE_RXDATA,
 | 
				
			||||||
 | 
					    //     .user = ctx,
 | 
				
			||||||
 | 
					    // };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//uint8_t buf[3] = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						assert(rx_data != nullptr);
 | 
				
			||||||
 | 
						assert(dataLen > 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spi_transaction_t trans_desc = {};
 | 
				
			||||||
 | 
						trans_desc.length    = dataLen * 8;
 | 
				
			||||||
 | 
						//trans_desc.tx_buffer = buf;
 | 
				
			||||||
 | 
						//trans_desc.cmd = 0x00;
 | 
				
			||||||
 | 
						trans_desc.rx_buffer = rx_data;
 | 
				
			||||||
 | 
						//trans_desc.rxlength = 0;
 | 
				
			||||||
 | 
					    esp_err_t rc = spi_device_polling_transmit(m_handle, &trans_desc);
 | 
				
			||||||
 | 
						//esp_err_t rc = spi_device_transmit(m_handle, &trans_desc);
 | 
				
			||||||
 | 
						if (rc != ESP_OK) {
 | 
				
			||||||
 | 
							ESP_LOGE(LOG_TAG, "transfer:spi_device_transmit: %d", rc);
 | 
				
			||||||
 | 
						}	
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SPI_drv::transfer(std::uint8_t* data, size_t dataLen) {
 | 
				
			||||||
 | 
						assert(data != nullptr);
 | 
				
			||||||
 | 
						assert(dataLen > 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spi_transaction_t trans_desc = {};
 | 
				
			||||||
 | 
						trans_desc.length    = dataLen * 8;
 | 
				
			||||||
 | 
						trans_desc.tx_buffer = data;
 | 
				
			||||||
 | 
					    esp_err_t rc = spi_device_polling_transmit(m_handle, &trans_desc);
 | 
				
			||||||
 | 
						//esp_err_t rc = spi_device_transmit(m_handle, &trans_desc);
 | 
				
			||||||
 | 
						if (rc != ESP_OK) {
 | 
				
			||||||
 | 
							ESP_LOGE(LOG_TAG, "transfer:spi_device_transmit: %d", rc);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					} // transmit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SPI_drv::cmd_write(std::uint16_t command, std::uint8_t* transfer_data, std::uint8_t byte2write){
 | 
				
			||||||
 | 
						spi_transaction_t trans_desc = {};
 | 
				
			||||||
 | 
						trans_desc.cmd      = command;
 | 
				
			||||||
 | 
						trans_desc.length   = (byte2write)*8;
 | 
				
			||||||
 | 
						trans_desc.tx_buffer = transfer_data;
 | 
				
			||||||
 | 
						esp_err_t rc = spi_device_polling_transmit(m_handle, &trans_desc);
 | 
				
			||||||
 | 
						//esp_err_t rc = spi_device_transmit(m_handle, &trans_desc);
 | 
				
			||||||
 | 
						if (rc != ESP_OK) {
 | 
				
			||||||
 | 
							ESP_LOGE(LOG_TAG, "transfer:spi_device_transmit: %d", rc);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SPI_drv::cmd_read(std::uint16_t command, std::uint8_t* read_data,std::uint8_t byte2read){
 | 
				
			||||||
 | 
						spi_transaction_t trans_desc = {};
 | 
				
			||||||
 | 
						trans_desc.length    =  byte2read*8;
 | 
				
			||||||
 | 
						trans_desc.cmd       =  command;
 | 
				
			||||||
 | 
						//trans_desc.rxlength  = 0;
 | 
				
			||||||
 | 
						//trans_desc.flags     = SPI_TRANS_USE_RXDATA;
 | 
				
			||||||
 | 
						trans_desc.rx_buffer = read_data;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    esp_err_t rc = spi_device_polling_transmit(m_handle, &trans_desc);
 | 
				
			||||||
 | 
						//esp_err_t rc = spi_device_transmit(m_handle, &trans_desc);
 | 
				
			||||||
 | 
						//*read_data = trans_desc.rx_data[0];
 | 
				
			||||||
 | 
						if (rc != ESP_OK) {
 | 
				
			||||||
 | 
							ESP_LOGE(LOG_TAG, "transfer:spi_device_transmit: %d", rc);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint8_t SPI_drv::transferByte(std::uint8_t value) {
 | 
				
			||||||
 | 
						transfer(&value, 1);
 | 
				
			||||||
 | 
						return value;
 | 
				
			||||||
 | 
					} // transferByte
 | 
				
			||||||
							
								
								
									
										19
									
								
								src/components/SPI_drv/SPI_drv.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/components/SPI_drv/SPI_drv.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					#include <cstdint>
 | 
				
			||||||
 | 
					#include <driver/spi_master.h>
 | 
				
			||||||
 | 
					#include <driver/gpio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SPI_drv {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						SPI_drv();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void 			init(spi_host_device_t host, int freq = 1000000, gpio_num_t cs_pin = GPIO_NUM_NC, bool useMiso = false, uint8_t spiMode = 0, uint32_t flags = 0);
 | 
				
			||||||
 | 
						void    		transfer(std::uint8_t* data, size_t dataLen);
 | 
				
			||||||
 | 
						void    		receive(std::uint8_t* rx_data, size_t dataLen);
 | 
				
			||||||
 | 
						std::uint8_t 	transferByte(std::uint8_t value);
 | 
				
			||||||
 | 
						void			cmd_write(std::uint16_t command, std::uint8_t* transfer_data, std::uint8_t byte2write);
 | 
				
			||||||
 | 
						void			cmd_read (std::uint16_t command, std::uint8_t* read_data,std::uint8_t byte2read);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					  spi_device_handle_t m_handle;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										251
									
								
								src/components/esp-nimble-cpp-1.3.3/CHANGELOG.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										251
									
								
								src/components/esp-nimble-cpp-1.3.3/CHANGELOG.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,251 @@
 | 
				
			|||||||
 | 
					# Changelog
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					All notable changes to this project will be documented in this file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## [1.3.3] - 2022-02-15
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Changed
 | 
				
			||||||
 | 
					- If attribute retrieval fails with a "not found" try again with the 16 bit version if a 128 bit base uuid is used.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Fixed
 | 
				
			||||||
 | 
					- Memory leak when deleting client instance.
 | 
				
			||||||
 | 
					- IDf version check for data length extension.
 | 
				
			||||||
 | 
					- Memory leak when server services changed.
 | 
				
			||||||
 | 
					- Compiler warnings for non-esp32 devices.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## [1.3.2] - 2022-01-15
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Fixed
 | 
				
			||||||
 | 
					- Initialize advertising complete callback in NimBLEAdvertising constructor.
 | 
				
			||||||
 | 
					- Clear client disconnect timer in constructor before initializing.
 | 
				
			||||||
 | 
					- Fix missing data when reading large values.
 | 
				
			||||||
 | 
					- Fix missing data in notifications when using a large MTU size and more than 270 bytes of data are sent.
 | 
				
			||||||
 | 
					- Workaround fix added for cases when the task notification value is not cleared, causing various functions that should block not to block.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Added
 | 
				
			||||||
 | 
					- `NimBLEClient::getLastError` : Gets the error code of the last function call that produces a return code from the stack.
 | 
				
			||||||
 | 
					- `NimBLECharacteristic::notify` : Overload method to send notifications/indications with custom values.
 | 
				
			||||||
 | 
					- Added conditional checks for ESP32 specific functions/values to support use of the library on non-esp32 devices.
 | 
				
			||||||
 | 
					- Added an alias to use the callback name from the original library `onMtuChanged`.
 | 
				
			||||||
 | 
					- `NimBLEClient::setDataLen` and `NimBLEServer::setDataLen`:  Data length extension support (IDF version >= 4.3.2 only)
 | 
				
			||||||
 | 
					- Config option to set logging level for esp-nimble-cpp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Changed
 | 
				
			||||||
 | 
					- Critical section calls now use the NimBLE API instead of FreeRTOS directly. This removes the need for a `portMUX_TYPE` variable in the class definitions.
 | 
				
			||||||
 | 
					- Removed unnecessary variables in `NimBLEService` and changed the constructor no no longer accept `numHandles` and `inst_id` parameters.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## [1.3.1] - 2021-08-04
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Fixed
 | 
				
			||||||
 | 
					- Corrected a compiler/linker error when an application or a library uses bluetooth classic due to the redefinition of `btInUse`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## [1.3.0] - 2021-08-02
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Added
 | 
				
			||||||
 | 
					- `NimBLECharacteristic::removeDescriptor`: Dynamically remove a descriptor from a characterisic. Takes effect after all connections are closed and sends a service changed indication.
 | 
				
			||||||
 | 
					- `NimBLEService::removeCharacteristic`: Dynamically remove a characteristic from a service. Takes effect after all connections are closed and sends a service changed indication
 | 
				
			||||||
 | 
					- `NimBLEServerCallbacks::onMTUChange`: This is callback is called when the MTU is updated after connection with a client.
 | 
				
			||||||
 | 
					- ESP32C3 support
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Whitelist API:
 | 
				
			||||||
 | 
					  - `NimBLEDevice::whiteListAdd`: Add a device to the whitelist.
 | 
				
			||||||
 | 
					  - `NimBLEDevice::whiteListRemove`: Remove a device from the whitelist.
 | 
				
			||||||
 | 
					  - `NimBLEDevice::onWhiteList`: Check if the device is on the whitelist.
 | 
				
			||||||
 | 
					  - `NimBLEDevice::getWhiteListCount`: Gets the size of the whitelist
 | 
				
			||||||
 | 
					  - `NimBLEDevice::getWhiteListAddress`: Get the address of a device on the whitelist by index value.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Bond management API:
 | 
				
			||||||
 | 
					  - `NimBLEDevice::getNumBonds`: Gets the number of bonds stored.
 | 
				
			||||||
 | 
					  - `NimBLEDevice::isBonded`: Checks if the device is bonded.
 | 
				
			||||||
 | 
					  - `NimBLEDevice::deleteAllBonds`: Deletes all bonds.
 | 
				
			||||||
 | 
					  - `NimBLEDevice::getBondedAddress`: Gets the address of a bonded device by the index value.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `NimBLECharacteristic::getCallbacks` to retrieve the current callback handler.
 | 
				
			||||||
 | 
					- Connection Information class: `NimBLEConnInfo`.
 | 
				
			||||||
 | 
					- `NimBLEScan::clearDuplicateCache`: This can be used to reset the cache of advertised devices so they will be immediately discovered again.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Changed
 | 
				
			||||||
 | 
					- FreeRTOS files have been removed as they are not used by the library.
 | 
				
			||||||
 | 
					- Services, characteristics and descriptors can now be created statically and added after.
 | 
				
			||||||
 | 
					- Excess logging and some asserts removed.
 | 
				
			||||||
 | 
					- Use ESP_LOGx macros to enable using local log level filtering.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Fixed
 | 
				
			||||||
 | 
					- `NimBLECharacteristicCallbacks::onSubscribe` Is now called after the connection is added to the vector.
 | 
				
			||||||
 | 
					- Corrected bonding failure when reinitializing the BLE stack.
 | 
				
			||||||
 | 
					- Writing to a characterisic with a std::string value now correctly writes values with null characters.
 | 
				
			||||||
 | 
					- Retrieving remote descriptors now uses the characterisic end handle correctly.
 | 
				
			||||||
 | 
					- Missing data in long writes to remote descriptors.
 | 
				
			||||||
 | 
					- Hanging on task notification when sending an indication from the characteristic callback.
 | 
				
			||||||
 | 
					- BLE controller memory could be released when using Arduino as a component.
 | 
				
			||||||
 | 
					- Complile errors with NimBLE release 1.3.0.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## [1.2.0] - 2021-02-08
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Added
 | 
				
			||||||
 | 
					- `NimBLECharacteristic::getDescriptorByHandle`: Return the BLE Descriptor for the given handle.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `NimBLEDescriptor::getStringValue`: Get the value of this descriptor as a string.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `NimBLEServer::getServiceByHandle`: Get a service by its handle.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `NimBLEService::getCharacteristicByHandle`: Get a pointer to the characteristic object with the specified handle.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `NimBLEService::getCharacteristics`: Get the vector containing pointers to each characteristic associated with this service.  
 | 
				
			||||||
 | 
					Overloads to get a vector containing pointers to all the characteristics in a service with the UUID. (supports multiple same UUID's in a service)
 | 
				
			||||||
 | 
					  - `NimBLEService::getCharacteristics(const char *uuid)`
 | 
				
			||||||
 | 
					  - `NimBLEService::getCharacteristics(const NimBLEUUID &uuid)`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `NimBLEAdvertisementData` New methods:
 | 
				
			||||||
 | 
					  - `NimBLEAdvertisementData::addTxPower`: Adds transmission power to the advertisement.
 | 
				
			||||||
 | 
					  - `NimBLEAdvertisementData::setPreferredParams`: Adds connection parameters to the advertisement.
 | 
				
			||||||
 | 
					  - `NimBLEAdvertisementData::setURI`: Adds URI data to the advertisement.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `NimBLEAdvertising` New methods:
 | 
				
			||||||
 | 
					  - `NimBLEAdvertising::setName`: Set the name advertised.
 | 
				
			||||||
 | 
					  - `NimBLEAdvertising::setManufacturerData`: Adds manufacturer data to the advertisement.
 | 
				
			||||||
 | 
					  - `NimBLEAdvertising::setURI`: Adds URI data to the advertisement.
 | 
				
			||||||
 | 
					  - `NimBLEAdvertising::setServiceData`: Adds service data to the advertisement.
 | 
				
			||||||
 | 
					  - `NimBLEAdvertising::addTxPower`: Adds transmission power to the advertisement.
 | 
				
			||||||
 | 
					  - `NimBLEAdvertising::reset`: Stops the current advertising and resets the advertising data to the default values.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `NimBLEDevice::setScanFilterMode`: Set the controller duplicate filter mode for filtering scanned devices.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `NimBLEDevice::setScanDuplicateCacheSize`: Sets the number of advertisements filtered before the cache is reset.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `NimBLEScan::setMaxResults`:  This allows for setting a maximum number of advertised devices stored in the results vector.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `NimBLEAdvertisedDevice` New data retrieval methods added:
 | 
				
			||||||
 | 
					  - `haveAdvInterval/getAdvInterval`: checks if the interval is advertised / gets the advertisement interval value.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - `haveConnParams/getMinInterval/getMaxInterval`: checks if the parameters are advertised / get min value / get max value.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - `haveURI/getURI`: checks if a URI is advertised / gets the URI data.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - `haveTargetAddress/getTargetAddressCount/getTargetAddress(index)`: checks if a target address is present / gets a count of the addresses targeted / gets the address of the target at index.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Changed
 | 
				
			||||||
 | 
					- `nimconfig.h` (Arduino) is now easier to use.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `NimBLEServer::getServiceByUUID` Now takes an extra parameter of instanceID to support multiple services with the same UUID.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `NimBLEService::getCharacteristic` Now takes an extra parameter of instanceID to support multiple characteristics with the same UUID.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `NimBLEAdvertising` Transmission power is no longer advertised by default and can be added to the advertisement by calling `NimBLEAdvertising::addTxPower`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `NimBLEAdvertising` Custom scan response data can now be used without custom advertisment.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `NimBLEScan` Now uses the controller duplicate filter.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `NimBLEAdvertisedDevice` Has been refactored to store the complete advertisement payload and no longer parses the data from each advertisement.  
 | 
				
			||||||
 | 
					Instead the data will be parsed on-demand when the user application asks for specific data.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Fixed
 | 
				
			||||||
 | 
					- `NimBLEHIDDevice` Characteristics now use encryption, this resolves an issue with communicating with devices requiring encryption for HID devices.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## [1.1.0] - 2021-01-20
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Added
 | 
				
			||||||
 | 
					- `NimBLEDevice::setOwnAddrType` added to enable the use of random and random-resolvable addresses, by asukiaaa  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- New examples for securing and authenticating client/server connections, by mblasee.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `NimBLEAdvertising::SetMinPreferred` and `NimBLEAdvertising::SetMinPreferred` re-added.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Conditional checks added for command line config options in `nimconfig.h` to support custom configuration in platformio.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `NimBLEClient::setValue` Now takes an extra bool parameter `response` to enable the use of write with response (default = false).  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `NimBLEClient::getCharacteristic(uint16_t handle)` Enabling the use of the characteristic handle to be used to find 
 | 
				
			||||||
 | 
					the NimBLERemoteCharacteristic object.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `NimBLEHIDDevice` class added by wakwak-koba.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `NimBLEServerCallbacks::onDisconnect` overloaded callback added to provide a ble_gap_conn_desc parameter for the application  
 | 
				
			||||||
 | 
					to obtain information about the disconnected client.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Conditional checks in `nimconfig.h` for command line defined macros to support platformio config settings.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Changed
 | 
				
			||||||
 | 
					- `NimBLEAdvertising::start` now returns a bool value to indicate success/failure.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Some asserts were removed in `NimBLEAdvertising::start` and replaced with better return code handling and logging.    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- If a host reset event occurs, scanning and advertising will now only be restarted if their previous duration was indefinite.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `NimBLERemoteCharacteristic::subscribe` and `NimBLERemoteCharacteristic::registerForNotify` will now set the callback
 | 
				
			||||||
 | 
					regardless of the existance of the CCCD and return true unless the descriptor write operation failed.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Advertising tx power level is now sent in the advertisement packet instead of scan response.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `NimBLEScan` When the scan ends the scan stopped flag is now set before calling the scan complete callback (if used)  
 | 
				
			||||||
 | 
					this allows the starting of a new scan from the callback function.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Fixed
 | 
				
			||||||
 | 
					- Sometimes `NimBLEClient::connect` would hang on the task block if no event arrived to unblock.  
 | 
				
			||||||
 | 
					A time limit has been added to timeout appropriately.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- When getting descriptors for a characterisic the end handle of the service was used as a proxy for the characteristic end  
 | 
				
			||||||
 | 
					handle. This would be rejected by some devices and has been changed to use the next characteristic handle as the end when possible.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- An exception could occur when deleting a client instance if a notification arrived while the attribute vectors were being  
 | 
				
			||||||
 | 
					deleted. A flag has been added to prevent this.  
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					- An exception could occur after a host reset event when the host re-synced if the tasks that were stopped during the event did  
 | 
				
			||||||
 | 
					not finish processing. A yield has been added after re-syncing to allow tasks to finish before proceeding.  
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					- Occasionally the controller would fail to send a disconnected event causing the client to indicate it is connected  
 | 
				
			||||||
 | 
					and would be unable to reconnect. A timer has been added to reset the host/controller if it expires.  
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					- Occasionally the call to start scanning would get stuck in a loop on BLE_HS_EBUSY, this loop has been removed.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- 16bit and 32bit UUID's in some cases were not discovered or compared correctly if the device  
 | 
				
			||||||
 | 
					advertised them as 16/32bit but resolved them to 128bits. Both are now checked.  
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					- `FreeRTOS` compile errors resolved in latest Ardruino core and IDF v3.3.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Multiple instances of `time()` called inside critical sections caused sporadic crashes, these have been moved out of critical regions.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Advertisement type now correctly set when using non-connectable (advertiser only) mode.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Advertising payload length correction, now accounts for appearance.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- (Arduino) Ensure controller mode is set to BLE Only.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## [1.0.2] - 2020-09-13
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Changed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `NimBLEAdvertising::start` Now takes 2 optional parameters, the first is the duration to advertise for (in seconds), the second is a  
 | 
				
			||||||
 | 
					callback that is invoked when advertsing ends and takes a pointer to a `NimBLEAdvertising` object (similar to the `NimBLEScan::start` API).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- (Arduino) Maximum BLE connections can now be altered by only changing the value of `CONFIG_BT_NIMBLE_MAX_CONNECTIONS` in `nimconfig.h`.
 | 
				
			||||||
 | 
					Any changes to the controller max connection settings in `sdkconfig.h` will now have no effect when using this library.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- (Arduino) Revert the previous change to fix the advertising start delay. Instead a replacement fix that routes all BLE controller commands from  
 | 
				
			||||||
 | 
					a task running on core 0 (same as the controller) has been implemented. This improves response times and reliability for all BLE functions.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## [1.0.1] - 2020-09-02
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Added
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Empty `NimBLEAddress` constructor: `NimBLEAddress()` produces an address of 00:00:00:00:00:00 type 0.
 | 
				
			||||||
 | 
					- Documentation of the difference of NimBLEAddress::getNative vs the original bluedroid library.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Changed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- notify_callback typedef is now defined as std::function to enable the use of std::bind to call a class member function.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Fixed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Fix advertising start delay when first called.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## [1.0.0] - 2020-08-22
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					First stable release.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					All the original library functionality is complete and many extras added with full documentation.
 | 
				
			||||||
							
								
								
									
										58
									
								
								src/components/esp-nimble-cpp-1.3.3/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								src/components/esp-nimble-cpp-1.3.3/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
				
			|||||||
 | 
					# The following lines of boilerplate have to be in your project's
 | 
				
			||||||
 | 
					# CMakeLists in this exact order for cmake to work correctly
 | 
				
			||||||
 | 
					cmake_minimum_required(VERSION 3.5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					idf_build_get_property(__hack_component_targets __COMPONENT_TARGETS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if("esp-nimble-component" IN_LIST BUILD_COMPONENTS OR "__esp-nimble-component" IN_LIST __hack_component_targets)
 | 
				
			||||||
 | 
					    list(APPEND ESP_NIMBLE_PRIV_REQUIRES
 | 
				
			||||||
 | 
					        esp-nimble-component
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					elseif("nimble" IN_LIST BUILD_COMPONENTS OR "__nimble" IN_LIST __hack_component_targets)
 | 
				
			||||||
 | 
					    list(APPEND ESP_NIMBLE_PRIV_REQUIRES
 | 
				
			||||||
 | 
					        nimble
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if("arduino" IN_LIST BUILD_COMPONENTS OR __hack_component_targets MATCHES "__idf_arduino")
 | 
				
			||||||
 | 
					    list(APPEND ESP_NIMBLE_PRIV_REQUIRES
 | 
				
			||||||
 | 
					        arduino
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					idf_component_register(
 | 
				
			||||||
 | 
					  REQUIRED_IDF_TARGETS
 | 
				
			||||||
 | 
					    "esp32"
 | 
				
			||||||
 | 
					    "esp32s3"
 | 
				
			||||||
 | 
					    "esp32c3"
 | 
				
			||||||
 | 
					  INCLUDE_DIRS
 | 
				
			||||||
 | 
					    "src"
 | 
				
			||||||
 | 
					  SRCS
 | 
				
			||||||
 | 
					    "src/NimBLE2904.cpp"
 | 
				
			||||||
 | 
					    "src/NimBLEAddress.cpp"
 | 
				
			||||||
 | 
					    "src/NimBLEAdvertisedDevice.cpp"
 | 
				
			||||||
 | 
					    "src/NimBLEAdvertising.cpp"
 | 
				
			||||||
 | 
					    "src/NimBLEBeacon.cpp"
 | 
				
			||||||
 | 
					    "src/NimBLECharacteristic.cpp"
 | 
				
			||||||
 | 
					    "src/NimBLEClient.cpp"
 | 
				
			||||||
 | 
					    "src/NimBLEDescriptor.cpp"
 | 
				
			||||||
 | 
					    "src/NimBLEDevice.cpp"
 | 
				
			||||||
 | 
					    "src/NimBLEEddystoneTLM.cpp"
 | 
				
			||||||
 | 
					    "src/NimBLEEddystoneURL.cpp"
 | 
				
			||||||
 | 
					    "src/NimBLEHIDDevice.cpp"
 | 
				
			||||||
 | 
					    "src/NimBLERemoteCharacteristic.cpp"
 | 
				
			||||||
 | 
					    "src/NimBLERemoteDescriptor.cpp"
 | 
				
			||||||
 | 
					    "src/NimBLERemoteService.cpp"
 | 
				
			||||||
 | 
					    "src/NimBLEScan.cpp"
 | 
				
			||||||
 | 
					    "src/NimBLESecurity.cpp"
 | 
				
			||||||
 | 
					    "src/NimBLEServer.cpp"
 | 
				
			||||||
 | 
					    "src/NimBLEService.cpp"
 | 
				
			||||||
 | 
					    "src/NimBLEUtils.cpp"
 | 
				
			||||||
 | 
					    "src/NimBLEUUID.cpp"
 | 
				
			||||||
 | 
					  REQUIRES
 | 
				
			||||||
 | 
					    bt
 | 
				
			||||||
 | 
					    nvs_flash
 | 
				
			||||||
 | 
					  PRIV_REQUIRES
 | 
				
			||||||
 | 
					    ${ESP_NIMBLE_PRIV_REQUIRES}
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										56
									
								
								src/components/esp-nimble-cpp-1.3.3/CMakeLists.txt_idf3
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								src/components/esp-nimble-cpp-1.3.3/CMakeLists.txt_idf3
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,56 @@
 | 
				
			|||||||
 | 
					# The following lines of boilerplate have to be in your project's
 | 
				
			||||||
 | 
					# CMakeLists in this exact order for cmake to work correctly
 | 
				
			||||||
 | 
					cmake_minimum_required(VERSION 3.5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					set(SUPPORTED_TARGETS esp32)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					set(COMPONENT_SRCS
 | 
				
			||||||
 | 
					    "src/NimBLE2904.cpp"
 | 
				
			||||||
 | 
					    "src/NimBLEAddress.cpp"
 | 
				
			||||||
 | 
					    "src/NimBLEAdvertisedDevice.cpp"
 | 
				
			||||||
 | 
					    "src/NimBLEAdvertising.cpp"
 | 
				
			||||||
 | 
					    "src/NimBLEBeacon.cpp"
 | 
				
			||||||
 | 
					    "src/NimBLECharacteristic.cpp"
 | 
				
			||||||
 | 
					    "src/NimBLEClient.cpp"
 | 
				
			||||||
 | 
					    "src/NimBLEDescriptor.cpp"
 | 
				
			||||||
 | 
					    "src/NimBLEDevice.cpp"
 | 
				
			||||||
 | 
					    "src/NimBLEEddystoneTLM.cpp"
 | 
				
			||||||
 | 
					    "src/NimBLEEddystoneURL.cpp"
 | 
				
			||||||
 | 
					    "src/NimBLEHIDDevice.cpp"
 | 
				
			||||||
 | 
					    "src/NimBLERemoteCharacteristic.cpp"
 | 
				
			||||||
 | 
					    "src/NimBLERemoteDescriptor.cpp"
 | 
				
			||||||
 | 
					    "src/NimBLERemoteService.cpp"
 | 
				
			||||||
 | 
					    "src/NimBLEScan.cpp"
 | 
				
			||||||
 | 
					    "src/NimBLESecurity.cpp"
 | 
				
			||||||
 | 
					    "src/NimBLEServer.cpp"
 | 
				
			||||||
 | 
					    "src/NimBLEService.cpp"
 | 
				
			||||||
 | 
					    "src/NimBLEUtils.cpp"
 | 
				
			||||||
 | 
					    "src/NimBLEUUID.cpp"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					set(COMPONENT_ADD_INCLUDEDIRS
 | 
				
			||||||
 | 
					    src
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					set(COMPONENT_PRIV_REQUIRES
 | 
				
			||||||
 | 
					    nvs_flash
 | 
				
			||||||
 | 
					    bt
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if(COMPONENTS MATCHES "esp-nimble-component")
 | 
				
			||||||
 | 
					    list(APPEND COMPONENT_PRIV_REQUIRES
 | 
				
			||||||
 | 
					        esp-nimble-component
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					elseif(COMPONENTS MATCHES "nimble")
 | 
				
			||||||
 | 
					    list(APPEND COMPONENT_PRIV_REQUIRES
 | 
				
			||||||
 | 
					        nimble
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if(COMPONENTS MATCHES "arduino")
 | 
				
			||||||
 | 
					    list(APPEND COMPONENT_PRIV_REQUIRES
 | 
				
			||||||
 | 
					        arduino
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					register_component()
 | 
				
			||||||
							
								
								
									
										53
									
								
								src/components/esp-nimble-cpp-1.3.3/Kconfig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								src/components/esp-nimble-cpp-1.3.3/Kconfig
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,53 @@
 | 
				
			|||||||
 | 
					menu "ESP-NimBLE-CPP configuration"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					choice NIMBLE_CPP_LOG_LEVEL
 | 
				
			||||||
 | 
					    prompt "NimBLE CPP log verbosity"
 | 
				
			||||||
 | 
					    default NIMBLE_CPP_LOG_LEVEL_NONE
 | 
				
			||||||
 | 
					    help
 | 
				
			||||||
 | 
					        Select NimBLE CPP log verbosity level.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    config NIMBLE_CPP_LOG_LEVEL_NONE
 | 
				
			||||||
 | 
					        bool "No logs"
 | 
				
			||||||
 | 
					    config NIMBLE_CPP_LOG_LEVEL_ERROR
 | 
				
			||||||
 | 
					        bool "Error logs"
 | 
				
			||||||
 | 
					    config NIMBLE_CPP_LOG_LEVEL_WARNING
 | 
				
			||||||
 | 
					        bool "Warning logs"
 | 
				
			||||||
 | 
					    config NIMBLE_CPP_LOG_LEVEL_INFO
 | 
				
			||||||
 | 
					        bool "Info logs"
 | 
				
			||||||
 | 
					    config NIMBLE_CPP_LOG_LEVEL_DEBUG
 | 
				
			||||||
 | 
					        bool "Debug logs"
 | 
				
			||||||
 | 
					endchoice #NIMBLE_CPP_LOG_LEVEL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					config NIMBLE_CPP_LOG_LEVEL
 | 
				
			||||||
 | 
					    int
 | 
				
			||||||
 | 
					    default 0 if NIMBLE_CPP_LOG_LEVEL_NONE
 | 
				
			||||||
 | 
					    default 1 if NIMBLE_CPP_LOG_LEVEL_ERROR
 | 
				
			||||||
 | 
					    default 2 if NIMBLE_CPP_LOG_LEVEL_WARNING
 | 
				
			||||||
 | 
					    default 3 if NIMBLE_CPP_LOG_LEVEL_INFO
 | 
				
			||||||
 | 
					    default 4 if NIMBLE_CPP_LOG_LEVEL_DEBUG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					config NIMBLE_CPP_ENABLE_RETURN_CODE_TEXT
 | 
				
			||||||
 | 
					    bool "Show NimBLE return codes as text in debug log."
 | 
				
			||||||
 | 
					    default "n"
 | 
				
			||||||
 | 
					    help
 | 
				
			||||||
 | 
					        Enabling this option will display return code values as text
 | 
				
			||||||
 | 
					        messages in the debug log. This will use approximately 8kB
 | 
				
			||||||
 | 
					        of flash memory.
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					config NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT
 | 
				
			||||||
 | 
					    bool "Show NimBLE gap events as text in debug log."
 | 
				
			||||||
 | 
					    default "n"
 | 
				
			||||||
 | 
					    help
 | 
				
			||||||
 | 
					        Enabling this option will display gap event codes as text
 | 
				
			||||||
 | 
					        messages in the debug log. This will use approximately 1kB
 | 
				
			||||||
 | 
					        of flash memory.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					config NIMBLE_CPP_ENABLE_ADVERTISMENT_TYPE_TEXT
 | 
				
			||||||
 | 
					    bool "Show advertisment types as text in debug log."
 | 
				
			||||||
 | 
					    default "n"
 | 
				
			||||||
 | 
					    help
 | 
				
			||||||
 | 
					        Enabling this option will display advertisment types recieved
 | 
				
			||||||
 | 
					        while scanning as text messages in the debug log. 
 | 
				
			||||||
 | 
					        This will use approximately 250 bytes of flash memory.
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					endmenu
 | 
				
			||||||
							
								
								
									
										203
									
								
								src/components/esp-nimble-cpp-1.3.3/LICENSE
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										203
									
								
								src/components/esp-nimble-cpp-1.3.3/LICENSE
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,203 @@
 | 
				
			|||||||
 | 
					                             Apache License
 | 
				
			||||||
 | 
					                           Version 2.0, January 2004
 | 
				
			||||||
 | 
					                        http://www.apache.org/licenses/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   1. Definitions.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      "License" shall mean the terms and conditions for use, reproduction,
 | 
				
			||||||
 | 
					      and distribution as defined by Sections 1 through 9 of this document.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      "Licensor" shall mean the copyright owner or entity authorized by
 | 
				
			||||||
 | 
					      the copyright owner that is granting the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      "Legal Entity" shall mean the union of the acting entity and all
 | 
				
			||||||
 | 
					      other entities that control, are controlled by, or are under common
 | 
				
			||||||
 | 
					      control with that entity. For the purposes of this definition,
 | 
				
			||||||
 | 
					      "control" means (i) the power, direct or indirect, to cause the
 | 
				
			||||||
 | 
					      direction or management of such entity, whether by contract or
 | 
				
			||||||
 | 
					      otherwise, or (ii) ownership of fifty percent (50%) or more of the
 | 
				
			||||||
 | 
					      outstanding shares, or (iii) beneficial ownership of such entity.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      "You" (or "Your") shall mean an individual or Legal Entity
 | 
				
			||||||
 | 
					      exercising permissions granted by this License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      "Source" form shall mean the preferred form for making modifications,
 | 
				
			||||||
 | 
					      including but not limited to software source code, documentation
 | 
				
			||||||
 | 
					      source, and configuration files.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      "Object" form shall mean any form resulting from mechanical
 | 
				
			||||||
 | 
					      transformation or translation of a Source form, including but
 | 
				
			||||||
 | 
					      not limited to compiled object code, generated documentation,
 | 
				
			||||||
 | 
					      and conversions to other media types.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      "Work" shall mean the work of authorship, whether in Source or
 | 
				
			||||||
 | 
					      Object form, made available under the License, as indicated by a
 | 
				
			||||||
 | 
					      copyright notice that is included in or attached to the work
 | 
				
			||||||
 | 
					      (an example is provided in the Appendix below).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      "Derivative Works" shall mean any work, whether in Source or Object
 | 
				
			||||||
 | 
					      form, that is based on (or derived from) the Work and for which the
 | 
				
			||||||
 | 
					      editorial revisions, annotations, elaborations, or other modifications
 | 
				
			||||||
 | 
					      represent, as a whole, an original work of authorship. For the purposes
 | 
				
			||||||
 | 
					      of this License, Derivative Works shall not include works that remain
 | 
				
			||||||
 | 
					      separable from, or merely link (or bind by name) to the interfaces of,
 | 
				
			||||||
 | 
					      the Work and Derivative Works thereof.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      "Contribution" shall mean any work of authorship, including
 | 
				
			||||||
 | 
					      the original version of the Work and any modifications or additions
 | 
				
			||||||
 | 
					      to that Work or Derivative Works thereof, that is intentionally
 | 
				
			||||||
 | 
					      submitted to Licensor for inclusion in the Work by the copyright owner
 | 
				
			||||||
 | 
					      or by an individual or Legal Entity authorized to submit on behalf of
 | 
				
			||||||
 | 
					      the copyright owner. For the purposes of this definition, "submitted"
 | 
				
			||||||
 | 
					      means any form of electronic, verbal, or written communication sent
 | 
				
			||||||
 | 
					      to the Licensor or its representatives, including but not limited to
 | 
				
			||||||
 | 
					      communication on electronic mailing lists, source code control systems,
 | 
				
			||||||
 | 
					      and issue tracking systems that are managed by, or on behalf of, the
 | 
				
			||||||
 | 
					      Licensor for the purpose of discussing and improving the Work, but
 | 
				
			||||||
 | 
					      excluding communication that is conspicuously marked or otherwise
 | 
				
			||||||
 | 
					      designated in writing by the copyright owner as "Not a Contribution."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      "Contributor" shall mean Licensor and any individual or Legal Entity
 | 
				
			||||||
 | 
					      on behalf of whom a Contribution has been received by Licensor and
 | 
				
			||||||
 | 
					      subsequently incorporated within the Work.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   2. Grant of Copyright License. Subject to the terms and conditions of
 | 
				
			||||||
 | 
					      this License, each Contributor hereby grants to You a perpetual,
 | 
				
			||||||
 | 
					      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
				
			||||||
 | 
					      copyright license to reproduce, prepare Derivative Works of,
 | 
				
			||||||
 | 
					      publicly display, publicly perform, sublicense, and distribute the
 | 
				
			||||||
 | 
					      Work and such Derivative Works in Source or Object form.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   3. Grant of Patent License. Subject to the terms and conditions of
 | 
				
			||||||
 | 
					      this License, each Contributor hereby grants to You a perpetual,
 | 
				
			||||||
 | 
					      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
				
			||||||
 | 
					      (except as stated in this section) patent license to make, have made,
 | 
				
			||||||
 | 
					      use, offer to sell, sell, import, and otherwise transfer the Work,
 | 
				
			||||||
 | 
					      where such license applies only to those patent claims licensable
 | 
				
			||||||
 | 
					      by such Contributor that are necessarily infringed by their
 | 
				
			||||||
 | 
					      Contribution(s) alone or by combination of their Contribution(s)
 | 
				
			||||||
 | 
					      with the Work to which such Contribution(s) was submitted. If You
 | 
				
			||||||
 | 
					      institute patent litigation against any entity (including a
 | 
				
			||||||
 | 
					      cross-claim or counterclaim in a lawsuit) alleging that the Work
 | 
				
			||||||
 | 
					      or a Contribution incorporated within the Work constitutes direct
 | 
				
			||||||
 | 
					      or contributory patent infringement, then any patent licenses
 | 
				
			||||||
 | 
					      granted to You under this License for that Work shall terminate
 | 
				
			||||||
 | 
					      as of the date such litigation is filed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   4. Redistribution. You may reproduce and distribute copies of the
 | 
				
			||||||
 | 
					      Work or Derivative Works thereof in any medium, with or without
 | 
				
			||||||
 | 
					      modifications, and in Source or Object form, provided that You
 | 
				
			||||||
 | 
					      meet the following conditions:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      (a) You must give any other recipients of the Work or
 | 
				
			||||||
 | 
					          Derivative Works a copy of this License; and
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      (b) You must cause any modified files to carry prominent notices
 | 
				
			||||||
 | 
					          stating that You changed the files; and
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      (c) You must retain, in the Source form of any Derivative Works
 | 
				
			||||||
 | 
					          that You distribute, all copyright, patent, trademark, and
 | 
				
			||||||
 | 
					          attribution notices from the Source form of the Work,
 | 
				
			||||||
 | 
					          excluding those notices that do not pertain to any part of
 | 
				
			||||||
 | 
					          the Derivative Works; and
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      (d) If the Work includes a "NOTICE" text file as part of its
 | 
				
			||||||
 | 
					          distribution, then any Derivative Works that You distribute must
 | 
				
			||||||
 | 
					          include a readable copy of the attribution notices contained
 | 
				
			||||||
 | 
					          within such NOTICE file, excluding those notices that do not
 | 
				
			||||||
 | 
					          pertain to any part of the Derivative Works, in at least one
 | 
				
			||||||
 | 
					          of the following places: within a NOTICE text file distributed
 | 
				
			||||||
 | 
					          as part of the Derivative Works; within the Source form or
 | 
				
			||||||
 | 
					          documentation, if provided along with the Derivative Works; or,
 | 
				
			||||||
 | 
					          within a display generated by the Derivative Works, if and
 | 
				
			||||||
 | 
					          wherever such third-party notices normally appear. The contents
 | 
				
			||||||
 | 
					          of the NOTICE file are for informational purposes only and
 | 
				
			||||||
 | 
					          do not modify the License. You may add Your own attribution
 | 
				
			||||||
 | 
					          notices within Derivative Works that You distribute, alongside
 | 
				
			||||||
 | 
					          or as an addendum to the NOTICE text from the Work, provided
 | 
				
			||||||
 | 
					          that such additional attribution notices cannot be construed
 | 
				
			||||||
 | 
					          as modifying the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      You may add Your own copyright statement to Your modifications and
 | 
				
			||||||
 | 
					      may provide additional or different license terms and conditions
 | 
				
			||||||
 | 
					      for use, reproduction, or distribution of Your modifications, or
 | 
				
			||||||
 | 
					      for any such Derivative Works as a whole, provided Your use,
 | 
				
			||||||
 | 
					      reproduction, and distribution of the Work otherwise complies with
 | 
				
			||||||
 | 
					      the conditions stated in this License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   5. Submission of Contributions. Unless You explicitly state otherwise,
 | 
				
			||||||
 | 
					      any Contribution intentionally submitted for inclusion in the Work
 | 
				
			||||||
 | 
					      by You to the Licensor shall be under the terms and conditions of
 | 
				
			||||||
 | 
					      this License, without any additional terms or conditions.
 | 
				
			||||||
 | 
					      Notwithstanding the above, nothing herein shall supersede or modify
 | 
				
			||||||
 | 
					      the terms of any separate license agreement you may have executed
 | 
				
			||||||
 | 
					      with Licensor regarding such Contributions.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   6. Trademarks. This License does not grant permission to use the trade
 | 
				
			||||||
 | 
					      names, trademarks, service marks, or product names of the Licensor,
 | 
				
			||||||
 | 
					      except as required for reasonable and customary use in describing the
 | 
				
			||||||
 | 
					      origin of the Work and reproducing the content of the NOTICE file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   7. Disclaimer of Warranty. Unless required by applicable law or
 | 
				
			||||||
 | 
					      agreed to in writing, Licensor provides the Work (and each
 | 
				
			||||||
 | 
					      Contributor provides its Contributions) on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 | 
				
			||||||
 | 
					      implied, including, without limitation, any warranties or conditions
 | 
				
			||||||
 | 
					      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
 | 
				
			||||||
 | 
					      PARTICULAR PURPOSE. You are solely responsible for determining the
 | 
				
			||||||
 | 
					      appropriateness of using or redistributing the Work and assume any
 | 
				
			||||||
 | 
					      risks associated with Your exercise of permissions under this License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   8. Limitation of Liability. In no event and under no legal theory,
 | 
				
			||||||
 | 
					      whether in tort (including negligence), contract, or otherwise,
 | 
				
			||||||
 | 
					      unless required by applicable law (such as deliberate and grossly
 | 
				
			||||||
 | 
					      negligent acts) or agreed to in writing, shall any Contributor be
 | 
				
			||||||
 | 
					      liable to You for damages, including any direct, indirect, special,
 | 
				
			||||||
 | 
					      incidental, or consequential damages of any character arising as a
 | 
				
			||||||
 | 
					      result of this License or out of the use or inability to use the
 | 
				
			||||||
 | 
					      Work (including but not limited to damages for loss of goodwill,
 | 
				
			||||||
 | 
					      work stoppage, computer failure or malfunction, or any and all
 | 
				
			||||||
 | 
					      other commercial damages or losses), even if such Contributor
 | 
				
			||||||
 | 
					      has been advised of the possibility of such damages.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   9. Accepting Warranty or Additional Liability. While redistributing
 | 
				
			||||||
 | 
					      the Work or Derivative Works thereof, You may choose to offer,
 | 
				
			||||||
 | 
					      and charge a fee for, acceptance of support, warranty, indemnity,
 | 
				
			||||||
 | 
					      or other liability obligations and/or rights consistent with this
 | 
				
			||||||
 | 
					      License. However, in accepting such obligations, You may act only
 | 
				
			||||||
 | 
					      on Your own behalf and on Your sole responsibility, not on behalf
 | 
				
			||||||
 | 
					      of any other Contributor, and only if You agree to indemnify,
 | 
				
			||||||
 | 
					      defend, and hold each Contributor harmless for any liability
 | 
				
			||||||
 | 
					      incurred by, or claims asserted against, such Contributor by reason
 | 
				
			||||||
 | 
					      of your accepting any such warranty or additional liability.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   END OF TERMS AND CONDITIONS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   APPENDIX: How to apply the Apache License to your work.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      To apply the Apache License to your work, attach the following
 | 
				
			||||||
 | 
					      boilerplate notice, with the fields enclosed by brackets "{}"
 | 
				
			||||||
 | 
					      replaced with your own identifying information. (Don't include
 | 
				
			||||||
 | 
					      the brackets!)  The text should be enclosed in the appropriate
 | 
				
			||||||
 | 
					      comment syntax for the file format. We also recommend that a
 | 
				
			||||||
 | 
					      file or class name and description of purpose be included on the
 | 
				
			||||||
 | 
					      same "printed page" as the copyright notice for easier
 | 
				
			||||||
 | 
					      identification within third-party archives.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   Copyright {2020} {Ryan Powell}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   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.
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					   This product partly derives from esp32-snippets; Copyright 2017 Neil Kolban.
 | 
				
			||||||
							
								
								
									
										70
									
								
								src/components/esp-nimble-cpp-1.3.3/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								src/components/esp-nimble-cpp-1.3.3/README.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,70 @@
 | 
				
			|||||||
 | 
					[Latest release 
 | 
				
			||||||
 | 
					](https://github.com/h2zero/esp-nimble-cpp/releases/latest/)  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Need help? Have questions or suggestions? Join the [](https://gitter.im/NimBLE-Arduino/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# esp-nimble-cpp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NimBLE CPP library for use with ESP32 that attempts to maintain compatibility with the [nkolban cpp_uitls BLE API](https://github.com/nkolban/esp32-snippets/tree/master/cpp_utils).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**An Arduino version of this library, including NimBLE, can be [found here.](https://github.com/h2zero/NimBLE-Arduino)**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This library **significantly** reduces resource usage and improves performance for ESP32 BLE applications as compared    
 | 
				
			||||||
 | 
					with the bluedroid based library. The goal is to maintain, as much as reasonable, compatibility with the original   
 | 
				
			||||||
 | 
					library but refactored to use the NimBLE stack. In addition, this library will be more actively developed and maintained   
 | 
				
			||||||
 | 
					to provide improved capabilites and stability over the original.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Testing shows a nearly 50% reduction in flash use and approx. 100kB less ram consumed vs the original!**  
 | 
				
			||||||
 | 
					*Your results may vary*  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# What is NimBLE?
 | 
				
			||||||
 | 
					NimBLE is a completely open source Bluetooth Low Energy stack produced by [Apache](https://github.com/apache/mynewt-nimble).  
 | 
				
			||||||
 | 
					It is more suited to resource constrained devices than bluedroid and has now been ported to the ESP32 by Espressif.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Installation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### ESP-IDF v4.0+
 | 
				
			||||||
 | 
					Download as .zip and extract or clone into the components folder in your esp-idf project.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Run menuconfig, go to `Component config->Bluetooth` enable Bluetooth and in `Bluetooth host` NimBLE.  
 | 
				
			||||||
 | 
					Configure settings in `NimBLE Options`.  
 | 
				
			||||||
 | 
					`#include "NimBLEDevice.h"` in main.cpp.  
 | 
				
			||||||
 | 
					Call `NimBLEDevice::init("");` in `app_main`.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### ESP-IDF v3.2 & v3.3
 | 
				
			||||||
 | 
					The NimBLE component does not come with these versions of IDF (now included in 3.3.2 and above).  
 | 
				
			||||||
 | 
					A backport that works in these versions has been created and is [available here](https://github.com/h2zero/esp-nimble-component).  
 | 
				
			||||||
 | 
					Download or clone that repo into your project/components folder and run menuconfig.
 | 
				
			||||||
 | 
					Configure settings in `main menu -> NimBLE Options`.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`#include "NimBLEDevice.h"` in main.cpp.  
 | 
				
			||||||
 | 
					Call `NimBLEDevice::init("");` in `app_main`.  
 | 
				
			||||||
 | 
					<br/>  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Using 
 | 
				
			||||||
 | 
					This library is intended to be compatible with the original ESP32 BLE functions and types with minor changes.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you have not used the original Bluedroid library please refer to the [New user guide](docs/New_user_guide.md).  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you are familiar with the original library, see: [The migration guide](docs/Migration_guide.md) for details about breaking changes and migration.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Also see [Improvements_and_updates](docs/Improvements_and_updates.md) for information about non-breaking changes.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[Full API documentation and class list can be found here.](https://h2zero.github.io/esp-nimble-cpp/)  
 | 
				
			||||||
 | 
					<br/>  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Using with Arduino as an IDF component and CMake
 | 
				
			||||||
 | 
					When using this library along with Arduino and compiling with *CMake* you must add `add_compile_definitions(ARDUINO_ARCH_ESP32=1)`  
 | 
				
			||||||
 | 
					in your project/CMakeLists.txt after the line `include($ENV{IDF_PATH}/tools/cmake/project.cmake)` to prevent Arduino from releasing BLE memory.
 | 
				
			||||||
 | 
					<br>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Acknowledgments
 | 
				
			||||||
 | 
					* [nkolban](https://github.com/nkolban) and [chegewara](https://github.com/chegewara) for the [original esp32 BLE library](https://github.com/nkolban/esp32-snippets/tree/master/cpp_utils) this project was derived from.
 | 
				
			||||||
 | 
					* [beegee-tokyo](https://github.com/beegee-tokyo) for contributing your time to test/debug and contributing the beacon examples.
 | 
				
			||||||
 | 
					* [Jeroen88](https://github.com/Jeroen88) for the amazing help debugging and improving the client code.  
 | 
				
			||||||
 | 
					<br/>  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										2
									
								
								src/components/esp-nimble-cpp-1.3.3/component.mk
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								src/components/esp-nimble-cpp-1.3.3/component.mk
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					COMPONENT_ADD_INCLUDEDIRS := src
 | 
				
			||||||
 | 
					COMPONENT_SRCDIRS := src
 | 
				
			||||||
							
								
								
									
										124
									
								
								src/components/esp-nimble-cpp-1.3.3/docs/Command_line_config.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								src/components/esp-nimble-cpp-1.3.3/docs/Command_line_config.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,124 @@
 | 
				
			|||||||
 | 
					# Arduino command line and platformio config options  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`CONFIG_BT_NIMBLE_MAX_CONNECTIONS`  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Sets the number of simultaneous connections (esp controller max is 9)  
 | 
				
			||||||
 | 
					- Default value is 3  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU`  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Sets the default MTU size.  
 | 
				
			||||||
 | 
					- Default value is 255  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`CONFIG_BT_NIMBLE_SVC_GAP_DEVICE_NAME`  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Set the default device name  
 | 
				
			||||||
 | 
					- Default value is "nimble"  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`CONFIG_BT_NIMBLE_DEBUG`   
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If defined, enables debug log messages from the NimBLE host  
 | 
				
			||||||
 | 
					- Uses approx. 32kB of flash memory.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`CONFIG_NIMBLE_CPP_LOG_LEVEL`   
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Define to set the debug log message level from the NimBLE CPP Wrapper.  
 | 
				
			||||||
 | 
					If not defined it will use the same value as the Arduino core debug level.  
 | 
				
			||||||
 | 
					Values: 0 = NONE, 1 = ERROR, 2 = WARNING, 3 = INFO, 4+ = DEBUG  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`CONFIG_NIMBLE_CPP_ENABLE_RETURN_CODE_TEXT`  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If defined, NimBLE host return codes will be printed as text in debug log messages.  
 | 
				
			||||||
 | 
					- Uses approx. 7kB of flash memory.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`CONFIG_NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT`  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If defined, GAP event codes will be printed as text in debug log messages.  
 | 
				
			||||||
 | 
					- Uses approx. 1kB of flash memory.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`CONFIG_NIMBLE_CPP_ENABLE_ADVERTISMENT_TYPE_TEXT`  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If defined, advertisment types will be printed as text while scanning in debug log messages.  
 | 
				
			||||||
 | 
					- Uses approx. 250 bytes of flash memory.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`CONFIG_BT_NIMBLE_SVC_GAP_APPEARANCE`  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Set the default appearance.  
 | 
				
			||||||
 | 
					- Default value is 0x00  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`CONFIG_BT_NIMBLE_ROLE_CENTRAL_DISABLED`  
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					If defined, NimBLE Client functions will not be included.  
 | 
				
			||||||
 | 
					- Reduces flash size by approx. 7kB.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`CONFIG_BT_NIMBLE_ROLE_OBSERVER_DISABLED`  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If defined, NimBLE Scan functions will not be included.  
 | 
				
			||||||
 | 
					- Reduces flash size by approx. 26kB.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`CONFIG_BT_NIMBLE_ROLE_PERIPHERAL_DISABLED`  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If defined NimBLE Server functions will not be included.  
 | 
				
			||||||
 | 
					- Reduces flash size by approx. 16kB.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`CONFIG_BT_NIMBLE_ROLE_BROADCASTER_DISABLED`  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If defined, NimBLE Advertising functions will not be included.  
 | 
				
			||||||
 | 
					- Reduces flash size by approx. 5kB.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`CONFIG_BT_NIMBLE_MAX_BONDS`  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Sets the number of devices allowed to store/bond with  
 | 
				
			||||||
 | 
					- Default value is 3  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`CONFIG_BT_NIMBLE_MAX_CCCDS`  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Sets the maximum number of CCCD subscriptions to store  
 | 
				
			||||||
 | 
					- Default value is 8  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`CONFIG_BT_NIMBLE_RPA_TIMEOUT`  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Sets the random address refresh time in seconds.  
 | 
				
			||||||
 | 
					- Default value is 900  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`CONFIG_BT_NIMBLE_MSYS1_BLOCK_COUNT`  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Set the number of msys blocks For prepare write & prepare responses. This may need to be increased if  
 | 
				
			||||||
 | 
					you are sending large blocks of data with a low MTU. E.g: 512 bytes with 23 MTU will fail.  
 | 
				
			||||||
 | 
					- Default value is 12  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL`  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Sets the NimBLE stack to use external PSRAM will be loaded  
 | 
				
			||||||
 | 
					- Must be defined with a value of 1; Default is CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL 1  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`CONFIG_BT_NIMBLE_PINNED_TO_CORE`  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Sets the core the NimBLE host stack will run on   
 | 
				
			||||||
 | 
					- Options: 0 or 1
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`CONFIG_BT_NIMBLE_TASK_STACK_SIZE`  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Set the task stack size for the NimBLE core.  
 | 
				
			||||||
 | 
					- Default is 4096  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										2669
									
								
								src/components/esp-nimble-cpp-1.3.3/docs/Doxyfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2669
									
								
								src/components/esp-nimble-cpp-1.3.3/docs/Doxyfile
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -0,0 +1,148 @@
 | 
				
			|||||||
 | 
					# Improvements and updates
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Many improvements have been made to this library vs the original, this is a brief overview of the most significant changes.  
 | 
				
			||||||
 | 
					Refer to the [class documentation](https://h2zero.github.io/esp-nimble-cpp/annotated.html) for futher information on class specifics.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* [Server](#server)
 | 
				
			||||||
 | 
					* [Advertising](#advertising)
 | 
				
			||||||
 | 
					* [Client](#client)
 | 
				
			||||||
 | 
					* [General](#general)  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<a name="server"></a>
 | 
				
			||||||
 | 
					# Server  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`NimBLECharacteristic::setValue(const T &s)`  
 | 
				
			||||||
 | 
					`NimBLEDescriptor::setValue(const T &s)`  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Now use a template to accomodate standard and custom types/values.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Example**
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					struct my_struct{
 | 
				
			||||||
 | 
					    uint8_t  one;
 | 
				
			||||||
 | 
					    uint16_t two;
 | 
				
			||||||
 | 
					    uint32_t four;
 | 
				
			||||||
 | 
					    uint64_t eight;
 | 
				
			||||||
 | 
					    float    flt;
 | 
				
			||||||
 | 
					}myStruct;
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					    myStruct.one = 1;
 | 
				
			||||||
 | 
					    myStruct.two = 2;
 | 
				
			||||||
 | 
					    myStruct.four = 4;
 | 
				
			||||||
 | 
					    myStruct.eight = 8;
 | 
				
			||||||
 | 
					    myStruct.flt = 1234.56;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pCharacteristic->setValue(myStruct);
 | 
				
			||||||
 | 
					 ```
 | 
				
			||||||
 | 
					This will send the struct to the recieving client when read or a notification sent.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`NimBLECharacteristic::getValue` now takes an optional timestamp parameter which will update it's value with  
 | 
				
			||||||
 | 
					the time the last value was recieved. In addition an overloaded template has been added to retrieve the value  
 | 
				
			||||||
 | 
					as a type specified by the user.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Example**
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					    time_t timestamp;
 | 
				
			||||||
 | 
					    myStruct = pCharacteristic->getValue<myStruct>(×tamp); // timestamp optional
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Advertising will automatically start when a client disconnects.**  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					A new method `NimBLEServer::advertiseOnDisconnect(bool)` has been implemented to control this, true(default) = enabled.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`NimBLEServer::removeService` takes an additional parameter `bool deleteSvc` that if true will delete the service  
 | 
				
			||||||
 | 
					and all characteristics / descriptors belonging to it and invalidating any pointers to them.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If false the service is only removed from visibility by clients. The pointers to the service and  
 | 
				
			||||||
 | 
					it's characteristics / descriptors will remain valid and the service can be re-added in the future  
 | 
				
			||||||
 | 
					using `NimBLEServer::addService`.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<a name="advertising"></a>
 | 
				
			||||||
 | 
					# Advertising
 | 
				
			||||||
 | 
					`NimBLEAdvertising::start`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Now takes 2 optional parameters, the first is the duration to advertise for (in seconds), the second is a callback  
 | 
				
			||||||
 | 
					that is invoked when advertsing ends and takes a pointer to a `NimBLEAdvertising` object (similar to the `NimBLEScan::start` API).  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This provides an opportunity to update the advertisment data if desired.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Also now returns a bool value to indicate if advertising successfully started or not.
 | 
				
			||||||
 | 
					<br/>  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<a name="client"></a>
 | 
				
			||||||
 | 
					# Client  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`NimBLERemoteCharacteristic::readValue(time_t\*, bool)`   
 | 
				
			||||||
 | 
					`NimBLERemoteDescriptor::readValue(bool)`  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Have been added as templates to allow reading the values as any specified type.   
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Example**
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					struct my_struct{
 | 
				
			||||||
 | 
					    uint8_t  one;
 | 
				
			||||||
 | 
					    uint16_t two;
 | 
				
			||||||
 | 
					    uint32_t four;
 | 
				
			||||||
 | 
					    uint64_t eight;
 | 
				
			||||||
 | 
					    float    flt;
 | 
				
			||||||
 | 
					}myStruct;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    time_t timestamp;
 | 
				
			||||||
 | 
					    myStruct = pRemoteCharacteristic->readValue<myStruct>(×tamp); // timestamp optional
 | 
				
			||||||
 | 
					```  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`NimBLERemoteCharacteristic::registerForNotify`  
 | 
				
			||||||
 | 
					Has been **deprecated** as now the internally stored characteristic value is updated when notification/indication is recieved.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`NimBLERemoteCharacteristic::subscribe` and `NimBLERemoteCharacteristic::unsubscribe` have been implemented to replace it.  
 | 
				
			||||||
 | 
					A callback is no longer requred to get the most recent value unless timing is important. Instead, the application can call `NimBLERemoteCharacteristic::getValue` to  
 | 
				
			||||||
 | 
					get the last updated value any time.  
 | 
				
			||||||
 | 
					<br/>  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The `notifiy_callback` function is now defined as a `std::function` to take advantage of using `std::bind` to specifiy a class member function for the callback.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Example:  
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					using namespace std::placeholders;
 | 
				
			||||||
 | 
					notify_callback callback = std::bind(&<ClassName>::<memberFunctionCallbackName>, this, _1, _2, _3, _4);
 | 
				
			||||||
 | 
					<remoteCharacteristicInstance>->subscribe(true, callback);
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`NimBLERemoteCharacteristic::readValue` and `NimBLERemoteCharacteristic::getValue` take an optional timestamp parameter which will update it's value with  
 | 
				
			||||||
 | 
					the time the last value was recieved.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					> NimBLEClient::getService  
 | 
				
			||||||
 | 
					> NimBLERemoteService::getCharacteristic  
 | 
				
			||||||
 | 
					> NimBLERemoteCharacteristic::getDescriptor  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					These methods will now check the respective vectors for the attribute object and, if not found, will retrieve (only)  
 | 
				
			||||||
 | 
					the specified attribute from the peripheral.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					These changes allow more control for the user to manage the resources used for the attributes.    
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`NimBLEClient::connect()` can now be called without an address or advertised device parameter. This will connect to the  
 | 
				
			||||||
 | 
					device with the address previously set when last connected or set with `NimBLEDevice::setPeerAddress()`. 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<a name="general"></a>
 | 
				
			||||||
 | 
					# General  
 | 
				
			||||||
 | 
					To reduce resource use all instances of `std::map` have been replaced with `std::vector`.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Use of `FreeRTOS::Semaphore` has been removed as it was consuming too much ram, the related files have been left in place to accomodate application use.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Operators `==`, `!=` and `std::string` have been added to `NimBLEAddress` and `NimBLEUUID` for easier comparison and logging.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					New constructor for `NimBLEUUID(uint32_t, uint16_t, uint16_t, uint64_t)` added to lower memory use vs string construction. See: [#21](https://github.com/h2zero/NimBLE-Arduino/pull/21).   
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Security/pairing operations are now handled in the respective `NimBLEClientCallbacks` and `NimBLEServerCallbacks` classes, `NimBLESecurity`(deprecated) remains for backward compatibility.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Configuration options have been added to add or remove debugging information, when disabled (default) significatly reduces binary size.  
 | 
				
			||||||
 | 
					In ESP-IDF the options are in menuconfig: `Main menu -> ESP-NimBLE-cpp configuration`.  
 | 
				
			||||||
 | 
					For Arduino the options must be commented / uncommented in nimconfig.h.   
 | 
				
			||||||
 | 
					<br/>  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										399
									
								
								src/components/esp-nimble-cpp-1.3.3/docs/Migration_guide.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										399
									
								
								src/components/esp-nimble-cpp-1.3.3/docs/Migration_guide.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,399 @@
 | 
				
			|||||||
 | 
					# Migrating from Bluedroid to NimBLE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This guide describes the required changes to existing projects migrating from the original bluedroid API to NimBLE.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**The changes listed here are only the required changes that must be made**, and a short overview of options for migrating existing applications.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For more information on the improvements and additions please refer to the [class documentation](https://h2zero.github.io/esp-nimble-cpp/annotated.html) and [Improvements and updates](Improvements_and_updates.md)  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* [General Changes](#general-information)
 | 
				
			||||||
 | 
					* [Server](#server-api)
 | 
				
			||||||
 | 
					    * [Services](#services)
 | 
				
			||||||
 | 
					    * [characteristics](#characteristics)
 | 
				
			||||||
 | 
					    * [descriptors](#descriptors)
 | 
				
			||||||
 | 
					    * [Security](#server-security)
 | 
				
			||||||
 | 
					* [Advertising](#advertising-api)
 | 
				
			||||||
 | 
					* [Client](#client-api)
 | 
				
			||||||
 | 
					    * [Remote Services](#remote-services)
 | 
				
			||||||
 | 
					    * [Remote characteristics](#remote-characteristics)
 | 
				
			||||||
 | 
					    * [Security](#client-security)
 | 
				
			||||||
 | 
					* [General Security](#security-api)
 | 
				
			||||||
 | 
					* [Configuration](#arduino-configuration)
 | 
				
			||||||
 | 
					<br/>  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<a name="general-information"></a>
 | 
				
			||||||
 | 
					## General Information
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Header Files
 | 
				
			||||||
 | 
					All classes are accessible by including `NimBLEDevice.h` in your application, no further headers need to be included.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(Mainly for Arduino) You may choose to include `NimBLELog.h` in your appplication if you want to use the `NIMBLE_LOGx` macros for debugging.  
 | 
				
			||||||
 | 
					These macros are used the same way as the `ESP_LOGx` macros.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Class Names
 | 
				
			||||||
 | 
					Class names remain the same as the original with the addition of a "Nim" prefix.  
 | 
				
			||||||
 | 
					For example `BLEDevice` is now `NimBLEDevice` and `BLEServer` is now `NimBLEServer` etc.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For convienience definitions have been added to allow applications to use either name for all classes  
 | 
				
			||||||
 | 
					this means **no class names need to be changed in existing code** and makes migrating easier.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### BLE Addresses
 | 
				
			||||||
 | 
					`BLEAddress` (`NimBLEAddress`) When constructing an address the constructor now takes an *(optional)* `uint8_t type` paramameter  
 | 
				
			||||||
 | 
					to specify the address type. Default is (0) Public static address.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For example `BLEAddress addr(11:22:33:44:55:66, 1)` will create the address object with an address type of: 1 (Random).  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					As this paramameter is optional no changes to existing code are needed, it is mentioned here for information.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					`BLEAddress::getNative` (`NimBLEAddress::getNative`) returns a uint8_t pointer to the native address byte array.  
 | 
				
			||||||
 | 
					In this library the address bytes are stored in reverse order from the original library. This is due to the way  
 | 
				
			||||||
 | 
					the NimBLE stack expects addresses to be presented to it. All other functions such as `toString` are  
 | 
				
			||||||
 | 
					not affected as the endian change is made within them.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<a name="server-api"></a>
 | 
				
			||||||
 | 
					## Server API
 | 
				
			||||||
 | 
					Creating a `BLEServer` instance is the same as original, no changes required.
 | 
				
			||||||
 | 
					For example `BLEDevice::createServer()` will work just as it did before.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`BLEServerCallbacks` (`NimBLEServerCallbacks`) has new methods for handling security operations.  
 | 
				
			||||||
 | 
					**Note:** All callback methods have default implementations which allows the application to implement only the methods applicable.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<a name="services"></a>
 | 
				
			||||||
 | 
					### Services
 | 
				
			||||||
 | 
					Creating a `BLEService` (`NimBLEService`) instance is the same as original, no changes required.  
 | 
				
			||||||
 | 
					For example `BLEServer::createService(SERVICE_UUID)` will work just as it did before.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<a name="characteristics"></a>
 | 
				
			||||||
 | 
					### Characteristics
 | 
				
			||||||
 | 
					`BLEService::createCharacteristic` (`NimBLEService::createCharacteristic`) is used the same way as originally except the properties parameter has changed.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					When creating a characteristic the properties are now set with `NIMBLE_PROPERTY::XXXX` instead of `BLECharacteristic::XXXX`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Originally
 | 
				
			||||||
 | 
					> BLECharacteristic::PROPERTY_READ |  
 | 
				
			||||||
 | 
					> BLECharacteristic::PROPERTY_WRITE  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Is Now
 | 
				
			||||||
 | 
					> NIMBLE_PROPERTY::READ |  
 | 
				
			||||||
 | 
					> NIMBLE_PROPERTY::WRITE  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### The full list of properties
 | 
				
			||||||
 | 
					> NIMBLE_PROPERTY::READ  
 | 
				
			||||||
 | 
					> NIMBLE_PROPERTY::READ_ENC  
 | 
				
			||||||
 | 
					> NIMBLE_PROPERTY::READ_AUTHEN  
 | 
				
			||||||
 | 
					> NIMBLE_PROPERTY::READ_AUTHOR  
 | 
				
			||||||
 | 
					> NIMBLE_PROPERTY::WRITE  
 | 
				
			||||||
 | 
					> NIMBLE_PROPERTY::WRITE_NR  
 | 
				
			||||||
 | 
					> NIMBLE_PROPERTY::WRITE_ENC  
 | 
				
			||||||
 | 
					> NIMBLE_PROPERTY::WRITE_AUTHEN  
 | 
				
			||||||
 | 
					> NIMBLE_PROPERTY::WRITE_AUTHOR  
 | 
				
			||||||
 | 
					> NIMBLE_PROPERTY::BROADCAST  
 | 
				
			||||||
 | 
					> NIMBLE_PROPERTY::NOTIFY   
 | 
				
			||||||
 | 
					> NIMBLE_PROPERTY::INDICATE  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Example:**
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					BLECharacteristic *pCharacteristic = pService->createCharacteristic(
 | 
				
			||||||
 | 
					                                     CHARACTERISTIC_UUID,
 | 
				
			||||||
 | 
					                                     BLECharacteristic::PROPERTY_READ   |
 | 
				
			||||||
 | 
					                                     BLECharacteristic::PROPERTY_WRITE  
 | 
				
			||||||
 | 
					                                     );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					Needs to be changed to:
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					BLECharacteristic *pCharacteristic = pService->createCharacteristic(
 | 
				
			||||||
 | 
					                                     CHARACTERISTIC_UUID,
 | 
				
			||||||
 | 
					                                     NIMBLE_PROPERTY::READ |
 | 
				
			||||||
 | 
					                                     NIMBLE_PROPERTY::WRITE 
 | 
				
			||||||
 | 
					                                    );
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`BLECharacteristicCallbacks` (`NimBLECharacteristicCallbacks`) has a new method `NimBLECharacteristicCallbacks::onSubscribe`  
 | 
				
			||||||
 | 
					which is called when a client subscribes to notifications/indications.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Note:** All callback methods have default implementations which allows the application to implement only the methods applicable.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					> BLECharacteristic::getData  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Has been removed from the API.**  
 | 
				
			||||||
 | 
					Originally this returned a `uint8_t*` to the internal data, which is volatile.  
 | 
				
			||||||
 | 
					To prevent possibly throwing exceptions this has been removed and `NimBLECharacteristic::getValue` should be used  
 | 
				
			||||||
 | 
					to get a copy of the data first which can then safely be accessed via pointer.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Example:**
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					std::string value = pCharacteristic->getValue();
 | 
				
			||||||
 | 
					uint8_t *pData = (uint8_t*)value.data();
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					Alternatively use the `getValue` template:
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					my_struct_t myStruct = pChr->getValue<my_struct_t>();
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<a name="descriptors"></a>
 | 
				
			||||||
 | 
					### Descriptors
 | 
				
			||||||
 | 
					The previous method `BLECharacteristic::addDescriptor()` has been removed.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Descriptors are now created using the `NimBLECharacteristic::createDescriptor` method.
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					BLE2902 or NimBLE2902 class has been removed.  
 | 
				
			||||||
 | 
					NimBLE automatically creates the 0x2902 descriptor if a characteristic has a notification or indication property assigned to it.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					It was no longer useful to have a class for the 0x2902 descriptor as a new callback `NimBLECharacteristicCallbacks::onSubscribe` was added  
 | 
				
			||||||
 | 
					to handle callback functionality and the client subscription status is handled internally.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Note:** Attempting to create a 0x2902 descriptor will trigger an assert to notify the error, 
 | 
				
			||||||
 | 
					allowing the creation of it would cause a fault in the NimBLE stack.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					All other descriptors are now created just as characteristics are by using the `NimBLECharacteristic::createDescriptor` method (except 0x2904, see below).   
 | 
				
			||||||
 | 
					Which are defined as:
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					NimBLEDescriptor* createDescriptor(const char* uuid,
 | 
				
			||||||
 | 
					                                   uint32_t properties = 
 | 
				
			||||||
 | 
					                                   NIMBLE_PROPERTY::READ |
 | 
				
			||||||
 | 
					                                   NIMBLE_PROPERTY::WRITE,
 | 
				
			||||||
 | 
					                                   uint16_t max_len = 100);
 | 
				
			||||||
 | 
					                                     
 | 
				
			||||||
 | 
					NimBLEDescriptor* createDescriptor(NimBLEUUID uuid,
 | 
				
			||||||
 | 
					                                   uint32_t properties = 
 | 
				
			||||||
 | 
					                                   NIMBLE_PROPERTY::READ |
 | 
				
			||||||
 | 
					                                   NIMBLE_PROPERTY::WRITE,
 | 
				
			||||||
 | 
					                                   uint16_t max_len = 100);
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					##### Example
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					pDescriptor = pCharacteristic->createDescriptor("ABCD", 
 | 
				
			||||||
 | 
					                                                NIMBLE_PROPERTY::READ | 
 | 
				
			||||||
 | 
					                                                NIMBLE_PROPERTY::WRITE |
 | 
				
			||||||
 | 
					                                                NIMBLE_PROPERTY::WRITE_ENC,
 | 
				
			||||||
 | 
					                                                25);
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					Would create a descriptor with the UUID 0xABCD, publicly readable but only writable if paired/bonded (encrypted) and has a max value length of 25 bytes.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For the 0x2904, there is a special class that is created when you call `createDescriptor("2904").
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The pointer returned is of the base class `NimBLEDescriptor` but the call will create the derived class of `NimBLE2904` so you must cast the returned pointer to  
 | 
				
			||||||
 | 
					`NimBLE2904` to access the specific class methods.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					##### Example
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					p2904 = (NimBLE2904*)pCharacteristic->createDescriptor("2904");
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<a name="server-security"></a>
 | 
				
			||||||
 | 
					### Server Security
 | 
				
			||||||
 | 
					Security is set on the characteristic or descriptor properties by applying one of the following:
 | 
				
			||||||
 | 
					> NIMBLE_PROPERTY::READ_ENC  
 | 
				
			||||||
 | 
					> NIMBLE_PROPERTY::READ_AUTHEN  
 | 
				
			||||||
 | 
					> NIMBLE_PROPERTY::READ_AUTHOR  
 | 
				
			||||||
 | 
					> NIMBLE_PROPERTY::WRITE_ENC  
 | 
				
			||||||
 | 
					> NIMBLE_PROPERTY::WRITE_AUTHEN  
 | 
				
			||||||
 | 
					> NIMBLE_PROPERTY::WRITE_AUTHOR  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					When a peer wants to read or write a characteristic or descriptor with any of these properties applied    
 | 
				
			||||||
 | 
					it will trigger the pairing process. By default the "just-works" pairing will be performed automatically.   
 | 
				
			||||||
 | 
					This can be changed to use passkey authentication or numeric comparison. See [Security API](#security-api) for details.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<a name="advertising-api"></a>
 | 
				
			||||||
 | 
					## Advertising API
 | 
				
			||||||
 | 
					Advertising works the same as the original API except:  
 | 
				
			||||||
 | 
					> BLEAdvertising::setMinPreferred  
 | 
				
			||||||
 | 
					> BLEAdvertising::setMaxPreferred  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					These methods were found to not provide useful functionality and consumed valuable advertising space (6 bytes of 31) if used unknowingly.  
 | 
				
			||||||
 | 
					If you wish to advertise these parameters you can still do so manually via `BLEAdvertisementData::addData` (`NimBLEAdvertisementData::addData`).  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Calling `NimBLEAdvertising::setAdvertisementData` will entirely replace any data set with `NimBLEAdvertising::addServiceUUID`, or  
 | 
				
			||||||
 | 
					`NimBLEAdvertising::setAppearance` or similar methods. You should set all the data you wish to advertise within the `NimBLEAdvertisementData` instead.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					~~Calling `NimBLEAdvertising::setScanResponseData` without also calling `NimBLEAdvertising::setAdvertisementData` will have no effect.  
 | 
				
			||||||
 | 
					When using custom scan response data you must also use custom advertisement data.~~  
 | 
				
			||||||
 | 
					No longer true as of release 1.2.0 and above, custom scan response is now supported without custom advertisement data.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					> BLEAdvertising::start (NimBLEAdvertising::start)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Now takes 2 optional parameters, the first is the duration to advertise for (in seconds), the second is a callback  
 | 
				
			||||||
 | 
					that is invoked when advertsing ends and takes a pointer to a `NimBLEAdvertising` object (similar to the `NimBLEScan::start` API).  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This provides an opportunity to update the advertisment data if desired.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<a name="client-api"></a>
 | 
				
			||||||
 | 
					## Client API
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Client instances are created just as before with `BLEDevice::createClient` (`NimBLEDevice::createClient`).  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Multiple client instances can be created, up to the maximum number of connections set in the config file (default: 3).  
 | 
				
			||||||
 | 
					To delete a client instance you must use `NimBLEDevice::deleteClient`.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`BLEClient::connect`(`NimBLEClient::connect`) Has had it's parameters altered.  
 | 
				
			||||||
 | 
					Defined as:
 | 
				
			||||||
 | 
					> NimBLEClient::connect(bool deleteServices = true);  
 | 
				
			||||||
 | 
					> NimBLEClient::connect(NimBLEAdvertisedDevice\* device, bool deleteServices = true);  
 | 
				
			||||||
 | 
					> NimBLEClient::connect(NimBLEAddress address, bool deleteServices = true);  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The type parameter has been removed and a new bool parameter has been added to indicate if the client should  
 | 
				
			||||||
 | 
					delete the attribute database previously retrieved (if applicable) for the peripheral, default value is true.  
 | 
				
			||||||
 | 
					If set to false the client will use the attribute database it retrieved from the peripheral when previously connected.  
 | 
				
			||||||
 | 
					This allows for faster connections and power saving if the devices dropped connection and are reconnecting.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					> `BLEClient::getServices` (`NimBLEClient::getServices`)  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This method now takes an optional (bool) parameter to indicate if the services should be retrieved from the server (true) or  
 | 
				
			||||||
 | 
					the currently known database returned (false : default).  
 | 
				
			||||||
 | 
					Also now returns a pointer to `std::vector` instead of `std::map`.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Removed:** the automatic discovery of all peripheral attributes as they consumed time and resources for data   
 | 
				
			||||||
 | 
					the user may not be interested in.  
 | 
				
			||||||
 | 
					   
 | 
				
			||||||
 | 
					**Added:** `NimBLEClient::discoverAttributes` for the user to discover all the peripheral attributes   
 | 
				
			||||||
 | 
					to replace the the removed automatic functionality.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<a name="remote-services"></a>
 | 
				
			||||||
 | 
					### Remote Services
 | 
				
			||||||
 | 
					`BLERemoteService` (`NimBLERemoteService`) Methods remain mostly unchanged with the exceptions of:  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					> BLERemoteService::getCharacteristicsByHandle
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This method has been removed.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					> `BLERemoteService::getCharacteristics` (`NimBLERemoteService::getCharacteristics`) 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This method now takes an optional (bool) parameter to indicate if the characteristics should be retrieved from the server (true) or  
 | 
				
			||||||
 | 
					the currently known database returned (false : default).  
 | 
				
			||||||
 | 
					Also now returns a pointer to `std::vector` instead of `std::map`.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<a name="remote-characteristics"></a>
 | 
				
			||||||
 | 
					### Remote Characteristics
 | 
				
			||||||
 | 
					`BLERemoteCharacteristic` (`NimBLERemoteCharacteristic`) There have been a few changes to the methods in this class:  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					> `BLERemoteCharacteristic::writeValue` (`NimBLERemoteCharacteristic::writeValue`)  
 | 
				
			||||||
 | 
					> `BLERemoteCharacteristic::registerForNotify` (`NimBLERemoteCharacteristic::registerForNotify`)  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Now return true or false to indicate success or failure so you can choose to disconnect or try again.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					> `BLERemoteCharacteristic::registerForNotify` (`NimBLERemoteCharacteristic::registerForNotify`)  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Is now **deprecated**.  
 | 
				
			||||||
 | 
					> `NimBLERemoteCharacteristic::subscribe`  
 | 
				
			||||||
 | 
					> `NimBLERemoteCharacteristic::unsubscribe`  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Are the new methods added to replace it.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					> `BLERemoteCharacteristic::readUInt8` (`NimBLERemoteCharacteristic::readUInt8`)  
 | 
				
			||||||
 | 
					> `BLERemoteCharacteristic::readUInt16` (`NimBLERemoteCharacteristic::readUInt16`)  
 | 
				
			||||||
 | 
					> `BLERemoteCharacteristic::readUInt32` (`NimBLERemoteCharacteristic::readUInt32`)  
 | 
				
			||||||
 | 
					> `BLERemoteCharacteristic::readFloat` (`NimBLERemoteCharacteristic::readFloat`)  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Are **deprecated** a template: NimBLERemoteCharacteristic::readValue<type\>(time_t\*, bool) has been added to replace them.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					> `BLERemoteCharacteristic::readRawData`  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Has been removed from the API**  
 | 
				
			||||||
 | 
					Originally it stored an unnecessary copy of the data and was returning a `uint8_t` pointer to volatile internal data.  
 | 
				
			||||||
 | 
					The user application should use `NimBLERemoteCharacteristic::readValue` or `NimBLERemoteCharacteristic::getValue`.  
 | 
				
			||||||
 | 
					To obatain a copy of the data, then cast the returned std::string to the type required such as:  
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					std::string value = pChr->readValue();
 | 
				
			||||||
 | 
					uint8_t *data = (uint8_t*)value.data();
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					Alternatively use the `readValue` template:
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					my_struct_t myStruct = pChr->readValue<my_struct_t>();
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					> `BLERemoteCharacteristic::getDescriptors` (`NimBLERemoteCharacteristic::getDescriptors`)      
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This method now takes an optional (bool) parameter to indicate if the descriptors should be retrieved from the server (true) or  
 | 
				
			||||||
 | 
					the currently known database returned (false : default).  
 | 
				
			||||||
 | 
					Also now returns a pointer to `std::vector` instead of `std::map`.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<a name="client-security"></a>
 | 
				
			||||||
 | 
					### Client Security
 | 
				
			||||||
 | 
					The client will automatically initiate security when the peripheral responds that it's required.  
 | 
				
			||||||
 | 
					The default configuration will use "just-works" pairing with no bonding, if you wish to enable bonding see below.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<a name="security-api"></a>
 | 
				
			||||||
 | 
					## Security API
 | 
				
			||||||
 | 
					Security operations have been moved to `BLEDevice` (`NimBLEDevice`).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Also security callback methods are now incorporated in the `NimBLEServerCallbacks` / `NimBLEClientCallbacks` classes.   
 | 
				
			||||||
 | 
					However backward compatibility with the original `BLESecurity` (`NimBLESecurity`) class is retained to minimize application code changes.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The callback methods are:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					> `bool onConfirmPIN(uint32_t pin)`  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Receives the pin when using numeric comparison authentication, `return true;` to accept.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					> `uint32_t onPassKeyRequest()`  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For server callback; return the passkey expected from the client.  
 | 
				
			||||||
 | 
					For client callback; return the passkey to send to the server.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					> `void onAuthenticationComplete(ble_gap_conn_desc\* desc)`  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Authentication complete, success or failed information is in `desc`.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Security settings and IO capabilities are now set by the following methods of NimBLEDevice.
 | 
				
			||||||
 | 
					> `NimBLEDevice::setSecurityAuth(bool bonding, bool mitm, bool sc)`  
 | 
				
			||||||
 | 
					> `NimBLEDevice::setSecurityAuth(uint8_t auth_req)`  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Sets the authorization mode for this device.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					> `NimBLEDevice::setSecurityIOCap(uint8_t iocap)`  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Sets the Input/Output capabilities of this device.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					> `NimBLEDevice::setSecurityInitKey(uint8_t init_key)`  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If we are the initiator of the security procedure this sets the keys we will distribute.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					> `NimBLEDevice::setSecurityRespKey(uint8_t resp_key)`  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Sets the keys we are willing to accept from the peer during pairing.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<a name="arduino-configuration"></a>
 | 
				
			||||||
 | 
					## Arduino Configuration
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unlike the original library pre-packaged in the esp32-arduino, this library has all the configuration  
 | 
				
			||||||
 | 
					options that are normally set in menuconfig available in the *src/nimconfig.h* file.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This allows Arduino users to fully customize the build, such as increasing max connections  
 | 
				
			||||||
 | 
					or loading the BLE stack into external PSRAM.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For details on the options, they are fully commented in *nimconfig.h*  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
							
								
								
									
										339
									
								
								src/components/esp-nimble-cpp-1.3.3/docs/New_user_guide.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										339
									
								
								src/components/esp-nimble-cpp-1.3.3/docs/New_user_guide.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,339 @@
 | 
				
			|||||||
 | 
					# New User Guide
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Note:** If you are migrating an existing project from the original Bluedroid library please see the [Migration Guide.](Migration_guide.md)  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you are a new user this will guide you through a simple server and client application.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* [Creating a Server](#creating-a-server)
 | 
				
			||||||
 | 
					* [Creating a Client](#creating-a-client)  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Include Files
 | 
				
			||||||
 | 
					At the top of your application file add `#include NimBLEDevice.h`, this is the only header required and provides access to all classes.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Using the Library
 | 
				
			||||||
 | 
					In order to perform any BLE tasks you must first initialize the library, this prepares the NimBLE stack to be ready for commands.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To do this you must call `NimBLEDevice::init("your device name here")`, the parameter passed is a character string containing the name you want to advertise.  
 | 
				
			||||||
 | 
					If you're not creating a server or do not want to advertise a name, simply pass an empty string for the parameter.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This can be called any time you wish to use BLE functions and does not need to be called from app_main(IDF) or setup(Arduino) but usually is.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<a name="creating-a-server"></a>
 | 
				
			||||||
 | 
					## Creating a Server
 | 
				
			||||||
 | 
					BLE servers perform 2 tasks, they advertise their existance for clients to find them and they provide services which contain information for the connecting client.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					After initializing the NimBLE stack we create a server by calling `NimBLEDevice::createServer()`, this will create a server instance and return a pointer to it.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Once we have created the server we need to tell it the services it hosts.  
 | 
				
			||||||
 | 
					To do this we call `NimBLEServer::createService(const char* uuid)`. Which returns a pointer to an instance of `NimBLEService`.  
 | 
				
			||||||
 | 
					The `uuid` parameter is a hexadecimal string with the uuid we want to give the service, it can be 16, 32, or 128 bits.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For this example we will keep it simple and use a 16 bit value: ABCD.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Example code:**  
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					#include "NimBLEDevice.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// void setup() in Arduino
 | 
				
			||||||
 | 
					void app_main(void)  
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    NimBLEDevice::init("NimBLE");
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    NimBLEServer *pServer = NimBLEDevice::createServer();
 | 
				
			||||||
 | 
					    NimBLEService *pService = pServer->createService("ABCD");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Now we have NimBLE initialized, a server created and a service assigned to it.  
 | 
				
			||||||
 | 
					We can't do much with this yet so now we should add a characteristic to the service to provide some data.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Next we call `NimBLEService::createCharacteristic` which returns a pointer to an instance of `NimBLECharacteristic`, and takes two parameters: 
 | 
				
			||||||
 | 
					A `uuid` to specify the UUID of the characteristic and a bitmask of the properties we want applied to it.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Just as with the service UUID we will use a simple 16 bit value: 1234.  
 | 
				
			||||||
 | 
					The properties bitmask is a little more involved. It is a combination of NIMBLE_PROPERTY:: values.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Here is the list of options:  
 | 
				
			||||||
 | 
					> NIMBLE_PROPERTY\::READ  
 | 
				
			||||||
 | 
					> NIMBLE_PROPERTY\::READ_ENC  
 | 
				
			||||||
 | 
					> NIMBLE_PROPERTY\::READ_AUTHEN  
 | 
				
			||||||
 | 
					> NIMBLE_PROPERTY\::READ_AUTHOR  
 | 
				
			||||||
 | 
					> NIMBLE_PROPERTY\::WRITE  
 | 
				
			||||||
 | 
					> NIMBLE_PROPERTY\::WRITE_NR  
 | 
				
			||||||
 | 
					> NIMBLE_PROPERTY\::WRITE_ENC  
 | 
				
			||||||
 | 
					> NIMBLE_PROPERTY\::WRITE_AUTHEN  
 | 
				
			||||||
 | 
					> NIMBLE_PROPERTY\::WRITE_AUTHOR  
 | 
				
			||||||
 | 
					> NIMBLE_PROPERTY\::BROADCAST  
 | 
				
			||||||
 | 
					> NIMBLE_PROPERTY\::NOTIFY  
 | 
				
			||||||
 | 
					> NIMBLE_PROPERTY\::INDICATE  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For this example we won't need to specify these as the default value is `NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE`  
 | 
				
			||||||
 | 
					which will allow reading and writing values to the characteristic without encryption or security.  
 | 
				
			||||||
 | 
					The function call will simply be `pService->createCharacteristic("1234");`  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Our example code now is:**  
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					#include "NimBLEDevice.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// void setup() in Arduino
 | 
				
			||||||
 | 
					void app_main(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    NimBLEDevice::init("NimBLE");
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    NimBLEServer *pServer = NimBLEDevice::createServer();
 | 
				
			||||||
 | 
					    NimBLEService *pService = pServer->createService("ABCD");
 | 
				
			||||||
 | 
					    NimBLECharacteristic *pCharacteristic = pService->createCharacteristic("1234");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					All that's left to do now is start the sevice, give the characteristic a value and start advertising for clients.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Fist we start the service by calling `NimBLEService::start()`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Next we need to call `NimBLECharacteristic::setValue` to set the characteristic value that the client will read.  
 | 
				
			||||||
 | 
					There are many different types you can send as parameters for the value but for this example we will use a simple string.
 | 
				
			||||||
 | 
					`pCharacteristic->setValue("Hello BLE");`  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Next we need to advertise for connections.  
 | 
				
			||||||
 | 
					To do this we create an instance of `NimBLEAdvertising` add our service to it (optional) and start advertisng.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**The code for this will be:**  
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					NimBLEAdvertising *pAdvertising = NimBLEDevice::getAdvertising(); // create advertising instance
 | 
				
			||||||
 | 
					pAdvertising->addServiceUUID("ABCD"); // tell advertising the UUID of our service
 | 
				
			||||||
 | 
					pAdvertising->start(); // start advertising
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					That's it, this will be enough to create a BLE server with a service and a characteristic and advertise for client connections.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**The full example code:**  
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					#include "NimBLEDevice.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// void setup() in Arduino
 | 
				
			||||||
 | 
					void app_main(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    NimBLEDevice::init("NimBLE");
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    NimBLEServer *pServer = NimBLEDevice::createServer();
 | 
				
			||||||
 | 
					    NimBLEService *pService = pServer->createService("ABCD");
 | 
				
			||||||
 | 
					    NimBLECharacteristic *pCharacteristic = pService->createCharacteristic("1234");
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    pService->start();
 | 
				
			||||||
 | 
					    pCharacteristic->setValue("Hello BLE");
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    NimBLEAdvertising *pAdvertising = NimBLEDevice::getAdvertising();
 | 
				
			||||||
 | 
					    pAdvertising->addServiceUUID("ABCD"); 
 | 
				
			||||||
 | 
					    pAdvertising->start(); 
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Now if you scan with your phone using nRFConnect or any other BLE app you should see a device named "NimBLE" with a service of "ABCD".  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For more advanced features and options please see the server examples in the examples folder.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<a name="creating-a-client"></a>
 | 
				
			||||||
 | 
					## Creating a Client 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BLE clients perform 2 tasks, they scan for advertising servers and form connections to them to read and write to their characteristics/descriptors.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					After initializing the NimBLE stack we create a scan instance by calling `NimBLEDevice::getScan()`, this will create a `NimBLEScan` instance and return a pointer to it.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Once we have created the scan we can start looking for advertising servers.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To do this we call `NimBLEScan::start(duration)`, the duration parameter is a uint32_t that specifies the number of seconds to scan for,  
 | 
				
			||||||
 | 
					passing 0 will scan forever.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In this example we will scan for 10 seconds. This is a blocking function (a non blocking overload is also available).  
 | 
				
			||||||
 | 
					This call returns an instance of `NimBLEScanResults` when the scan completes which can be parsed for advertisers we are interested in.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Example Code:**  
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					#include "NimBLEDevice.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// void setup() in Arduino
 | 
				
			||||||
 | 
					void app_main(void)  
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    NimBLEDevice::init("");
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    NimBLEScan *pScan = NimBLEDevice::getScan();
 | 
				
			||||||
 | 
					    NimBLEScanResults results = pScan->start(10);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Now that we have scanned we need to check the results for any advertisers we are interested in connecting to.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To do this we iterate through the results and check if any of the devices found are advertising the service we want `ABCD`.  
 | 
				
			||||||
 | 
					Each result in `NimBLEScanResults` is a `NimBLEAdvertisedDevice` instance that we can access data from.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					We will check each device found for the `ABCD` service by calling `NimBLEAdvertisedDevice::isAdvertisingService`.  
 | 
				
			||||||
 | 
					This takes an instance of `NimBLEUUID` as a parameter so we will need to create one.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**The code for this looks like:**
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					NimBLEUUID serviceUuid("ABCD");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					for(int i = 0; i < results.getCount(); i++) {
 | 
				
			||||||
 | 
					    NimBLEAdvertisedDevice device = results.getDevice(i);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (device.isAdvertisingService(serviceUuid)) {
 | 
				
			||||||
 | 
					    // create a client and connect
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Now that we can scan and parse advertisers we need to be able to create a `NimBLEClient` instance and use it to connect.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To do this we call `NimBLEDevice::createClient` which creates the `NimBLEClient` instance and returns a pointer to it.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					After this we call `NimBLEClient::connect` to connect to the advertiser.  
 | 
				
			||||||
 | 
					This takes a pointer to the `NimBLEAdvertisedDevice` and returns `true` if successful.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Lets do that now:**
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					NimBLEUUID serviceUuid("ABCD");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					for(int i = 0; i < results.getCount(); i++) {
 | 
				
			||||||
 | 
					    NimBLEAdvertisedDevice device = results.getDevice(i);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (device.isAdvertisingService(serviceUuid)) {
 | 
				
			||||||
 | 
					        NimBLEClient *pClient = NimBLEDevice::createClient();
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        if(pClient->connect(&device)) {
 | 
				
			||||||
 | 
					        //success
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					        // failed to connect
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					As shown, the call to `NimBLEClient::connect` should have it's eturn value tested to make sure it succeeded before proceeding to get data.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Next we need to access the servers data by asking it for the service and the characteristic we are interested in, then read the characteristic value. 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To do this we call `NimBLEClient::getService`, which takes as a parameter the UUID of the service and returns  
 | 
				
			||||||
 | 
					a pointer an instance to `NimBLERemoteService` or `nullptr` if the service was not found.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Next we will call `NimBLERemoteService::getCharateristic` which takes as a parameter the UUID of the service and returns  
 | 
				
			||||||
 | 
					a pointer to an instance of `NimBLERemoteCharacteristic` or `nullptr` if not found.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Finally we will read the characteristic value with `NimBLERemoteCharacteristic::readValue()`.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Here is what that looks like:**
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					NimBLEUUID serviceUuid("ABCD");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					for(int i = 0; i < results.getCount(); i++) {
 | 
				
			||||||
 | 
					    NimBLEAdvertisedDevice device = results.getDevice(i);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (device.isAdvertisingService(serviceUuid)) {
 | 
				
			||||||
 | 
					        NimBLEClient *pClient = NimBLEDevice::createClient();
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        if (pClient->connect(&device)) {
 | 
				
			||||||
 | 
					            NimBLERemoteService *pService = pClient->getService(serviceUuid);
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            if (pService != nullptr) {
 | 
				
			||||||
 | 
					                NimBLERemoteCharacteristic *pCharacteristic = pService->getCharacteristic("1234");
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                if (pCharacteristic != nullptr) {
 | 
				
			||||||
 | 
					                    std::string value = pCharacteristic->readValue();
 | 
				
			||||||
 | 
					                    // print or do whatever you need with the value
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					        // failed to connect
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The last thing we should do is clean up once we are done with the connection.  
 | 
				
			||||||
 | 
					Because multiple clients are supported and can be created we should delete them when finished with them to conserve resources.  
 | 
				
			||||||
 | 
					This is done by calling `NimBLEDevice::deleteClient`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Lets add that now:**
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					NimBLEUUID serviceUuid("ABCD");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					for(int i = 0; i < results.getCount(); i++) {
 | 
				
			||||||
 | 
					    NimBLEAdvertisedDevice device = results.getDevice(i);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (device.isAdvertisingService(serviceUuid)) {
 | 
				
			||||||
 | 
					        NimBLEClient *pClient = NimBLEDevice::createClient();
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        if (pClient->connect(&device)) {
 | 
				
			||||||
 | 
					            NimBLERemoteService *pService = pClient->getService(serviceUuid);
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            if (pService != nullptr) {
 | 
				
			||||||
 | 
					                NimBLERemoteCharacteristic *pCharacteristic = pService->getCharacteristic("1234");
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                if (pCharacteristic != nullptr) {
 | 
				
			||||||
 | 
					                    std::string value = pCharacteristic->readValue();
 | 
				
			||||||
 | 
					                    // print or do whatever you need with the value
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					        // failed to connect
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        NimBLEDevice::deleteClient(pClient);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					Note that there is no need to disconnect as that will be done when deleting the client instance.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Here is the full example code:**  
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					#include "NimBLEDevice.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// void setup() in Arduino
 | 
				
			||||||
 | 
					void app_main(void)  
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    NimBLEDevice::init("");
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    NimBLEScan *pScan = NimBLEDevice::getScan();
 | 
				
			||||||
 | 
					    NimBLEScanResults results = pScan->start(10);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    NimBLEUUID serviceUuid("ABCD");
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    for(int i = 0; i < results.getCount(); i++) {
 | 
				
			||||||
 | 
					        NimBLEAdvertisedDevice device = results.getDevice(i);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        if (device.isAdvertisingService(serviceUuid)) {
 | 
				
			||||||
 | 
					            NimBLEClient *pClient = NimBLEDevice::createClient();
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            if (pClient->connect(&device)) {
 | 
				
			||||||
 | 
					                NimBLERemoteService *pService = pClient->getService(serviceUuid);
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                if (pService != nullptr) {
 | 
				
			||||||
 | 
					                    NimBLERemoteCharacteristic *pCharacteristic = pService->getCharacteristic("1234");
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
 | 
					                    if (pCharacteristic != nullptr) {
 | 
				
			||||||
 | 
					                        std::string value = pCharacteristic->readValue();
 | 
				
			||||||
 | 
					                        // print or do whatever you need with the value
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					            // failed to connect
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            NimBLEDevice::deleteClient(pClient);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For more advanced features and options please see the client examples in the examples folder.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										41
									
								
								src/components/esp-nimble-cpp-1.3.3/docs/Usage_tips.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								src/components/esp-nimble-cpp-1.3.3/docs/Usage_tips.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
				
			|||||||
 | 
					# Usage Tips
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Put BLE functions in a task running on the NimBLE stack core
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					When commands are sent to the stack from a differnt core they can experience delays in execution.  
 | 
				
			||||||
 | 
					This library detects this and invokes the esp32 IPC to reroute these commands through the correct core but this also increases overhead.  
 | 
				
			||||||
 | 
					Therefore it is highly recommended to create tasks for BLE to run on the same core, the macro `CONFIG_BT_NIMBLE_PINNED_TO_CORE` can be used to set the core.
 | 
				
			||||||
 | 
					<br/>  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Do not delete client instances unless necessary or unused
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					When a client instance has been created and has connected to a peer device and it has retrieved service/characteristic information it will store that data for the life of the client instance.  
 | 
				
			||||||
 | 
					If you are periodically connecting to the same devices and you have deleted the client instance or the services when connecting again it will cause a retrieval of that information from the peer again.  
 | 
				
			||||||
 | 
					This results in significant energy drain on the battery of the devices, fragments heap, and reduces connection performance.  
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					Client instances in this library use approximately 20% of the original bluedroid library, deleteing them will provide much less gain than it did before.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					It is recommended to retain the client instance in cases where the time between connecting to the same device is less than 5 minutes.  
 | 
				
			||||||
 | 
					<br/>  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Only retrieve the services and characteriscs needed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					As a client the use of `NimBLEClient::getServices` or `NimBLERemoteService::getCharacteristics` and using `true` for the parameter should be limited to devices that are not known.  
 | 
				
			||||||
 | 
					Instead `NimBLEClient::getService(NimBLEUUID)` or `NimBLERemoteService::getCharacteristic(NimBLEUUID)` should be used to access certain attributes that are useful to the application.  
 | 
				
			||||||
 | 
					This reduces energy consumed, heap allocated, connection time and improves overall efficiency.  
 | 
				
			||||||
 | 
					<br/>  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Check return values
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Many user issues can be avoided by checking if a function returned successfully, by either testing for true/false such as when calling `NimBLEClient::connect`,  
 | 
				
			||||||
 | 
					or nullptr such as when  calling `NimBLEClient::getService`. The latter being a must, as calling a method on a nullptr will surely result in a crash.  
 | 
				
			||||||
 | 
					Most of the functions in this library return something that should be checked before proceeding.  
 | 
				
			||||||
 | 
					<br/>  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## There will be bugs - please report them
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					No code is bug free and unit testing will not find them all on it's own. If you encounter a bug, please report it along with any logs and decoded backtrace if applicable.  
 | 
				
			||||||
 | 
					Best efforts will be made to correct any errors ASAP.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Bug reports can be made at https://github.com/h2zero/NimBLE-Arduino/issues or https://github.com/h2zero/esp-nimble-cpp/issues.  
 | 
				
			||||||
 | 
					Questions and suggestions will be happily accepted there as well.
 | 
				
			||||||
							
								
								
									
										85
									
								
								src/components/esp-nimble-cpp-1.3.3/docs/index.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								src/components/esp-nimble-cpp-1.3.3/docs/index.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,85 @@
 | 
				
			|||||||
 | 
					# Overview
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This is a C++ BLE library for the ESP32 that uses the NimBLE host stack instead of bluedroid.  
 | 
				
			||||||
 | 
					The aim is to maintain, as much as reasonable, the original bluedroid C++ & Arduino BLE API by while adding new features  
 | 
				
			||||||
 | 
					and making improvements in performance, resource use, and stability.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Testing shows a nearly 50% reduction in flash use and approx. 100kB less ram consumed vs the original!**  
 | 
				
			||||||
 | 
					*Your results may vary*
 | 
				
			||||||
 | 
					<br/>  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# What is NimBLE?
 | 
				
			||||||
 | 
					NimBLE is a completely open source Bluetooth Low Energy stack produced by [Apache](https://github.com/apache/mynewt-nimble).  
 | 
				
			||||||
 | 
					It is more suited to resource constrained devices than bluedroid and has now been ported to the ESP32 by Espressif.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Arduino Installation
 | 
				
			||||||
 | 
					**Arduino Library manager:** Go to `sketch` -> `Include Library` -> `Manage Libraries` and search for NimBLE and install.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Alternatively:** Download as .zip and extract to Arduino/libraries folder, or in Arduino IDE from Sketch menu -> Include library -> Add .Zip library.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`#include "NimBLEDevice.h"` at the beginning of your sketch.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Call `NimBLEDevice::init` in `setup`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Tested and working with esp32-arduino in Arduino IDE and platform IO.  
 | 
				
			||||||
 | 
					<br/>  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# ESP-IDF Installation
 | 
				
			||||||
 | 
					### v4.0+
 | 
				
			||||||
 | 
					Download as .zip and extract or clone into the components folder in your esp-idf project.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Run menuconfig, go to `Component config->Bluetooth` enable Bluetooth and in `Bluetooth host` NimBLE.  
 | 
				
			||||||
 | 
					Configure settings in `NimBLE Options`.  
 | 
				
			||||||
 | 
					`#include "NimBLEDevice.h"` in main.cpp.  
 | 
				
			||||||
 | 
					Call `NimBLEDevice::init` in `app_main`.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### v3.2 & v3.3
 | 
				
			||||||
 | 
					The NimBLE component does not come with these versions of IDF (now included in 3.3.2 and above).   
 | 
				
			||||||
 | 
					A backport that works in these versions has been created and is [available here](https://github.com/h2zero/esp-nimble-component).  
 | 
				
			||||||
 | 
					Download or clone that repo into your project/components folder and run menuconfig.
 | 
				
			||||||
 | 
					Configure settings in `main menu -> NimBLE Options`.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`#include "NimBLEDevice.h"` in main.cpp.  
 | 
				
			||||||
 | 
					Call `NimBLEDevice::init` in `app_main`.  
 | 
				
			||||||
 | 
					<br/>  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Using
 | 
				
			||||||
 | 
					This library is intended to be compatible with the original ESP32 BLE functions and types with minor changes.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you have not used the original Bluedroid library please refer to the [New user guide](New_user_guide.md).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you are familiar with the original library, see: [The migration guide](Migration_guide.md) for details.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Also see [Improvements and updates](Improvements_and_updates.md) for information about non-breaking changes.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For more advanced usage see [Usage tips](Usage_tips.md) for more performance and optimization.  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Arduino specific
 | 
				
			||||||
 | 
					See the Refactored_original_examples in the examples folder for highlights of the differences with the original library.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					More advanced examples highlighting many available features are in examples/NimBLE_Server, NimBLE_Client.  
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					Beacon examples provided by [beegee-tokyo](https://github.com/beegee-tokyo) are in examples/BLE_Beacon_Scanner, BLE_EddystoneTLM_Beacon, BLE_EddystoneURL_Beacon.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Change the settings in the nimconfig.h file to customize NimBLE to your project, such as increasing max connections (default is 3).  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Arduino command line and platformio
 | 
				
			||||||
 | 
					As an alternative to changing the configuration in nimconfig.h, Arduino command line and platformio.ini options are available.  
 | 
				
			||||||
 | 
					See the command line configuration options available in [Command line config](Command_line_config.md).  
 | 
				
			||||||
 | 
					<br/>  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Need help? Have a question or suggestion?
 | 
				
			||||||
 | 
					Come chat on [gitter](https://gitter.im/NimBLE-Arduino/community?utm_source=share-link&utm_medium=link&utm_campaign=share-link) or open an issue at [NimBLE-Arduino](https://github.com/h2zero/NimBLE-Arduino/issues) or [esp-nimble-cpp](https://github.com/h2zero/esp-nimble-cpp/issues)  
 | 
				
			||||||
 | 
					<br/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Acknowledgments
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* [nkolban](https://github.com/nkolban) and [chegewara](https://github.com/chegewara) for the [original esp32 BLE library](https://github.com/nkolban/esp32-snippets/tree/master/cpp_utils) this project was derived from.
 | 
				
			||||||
 | 
					* [beegee-tokyo](https://github.com/beegee-tokyo) for contributing your time to test/debug and contributing the beacon examples.
 | 
				
			||||||
 | 
					* [Jeroen88](https://github.com/Jeroen88) for the amazing help debugging and improving the client code.
 | 
				
			||||||
 | 
					<br/>  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					# The following lines of boilerplate have to be in your project's
 | 
				
			||||||
 | 
					# CMakeLists in this exact order for cmake to work correctly
 | 
				
			||||||
 | 
					cmake_minimum_required(VERSION 3.5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include($ENV{IDF_PATH}/tools/cmake/project.cmake)
 | 
				
			||||||
 | 
					set(SUPPORTED_TARGETS esp32)
 | 
				
			||||||
 | 
					project(NimBLE_Client)
 | 
				
			||||||
@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					PROJECT_NAME := NimBLE_Client
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include $(IDF_PATH)/make/project.mk
 | 
				
			||||||
@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					set(COMPONENT_SRCS "main.cpp")
 | 
				
			||||||
 | 
					set(COMPONENT_ADD_INCLUDEDIRS ".")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					register_component()
 | 
				
			||||||
@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					#
 | 
				
			||||||
 | 
					# "main" pseudo-component makefile.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
 | 
				
			||||||
@@ -0,0 +1,372 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					/** NimBLE_Server Demo:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Demonstrates many of the available features of the NimBLE client library.
 | 
				
			||||||
 | 
					 *  
 | 
				
			||||||
 | 
					 *  Created: on March 24 2020
 | 
				
			||||||
 | 
					 *      Author: H2zero
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					#include <NimBLEDevice.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern "C" {void app_main(void);}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void scanEndedCB(NimBLEScanResults results);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static NimBLEAdvertisedDevice* advDevice;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool doConnect = false;
 | 
				
			||||||
 | 
					static uint32_t scanTime = 0; /** 0 = scan forever */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**  None of these are required as they will be handled by the library with defaults. **
 | 
				
			||||||
 | 
					 **                       Remove as you see fit for your needs                        */  
 | 
				
			||||||
 | 
					class ClientCallbacks : public NimBLEClientCallbacks {
 | 
				
			||||||
 | 
					    void onConnect(NimBLEClient* pClient) {
 | 
				
			||||||
 | 
					        printf("Connected\n");
 | 
				
			||||||
 | 
					        /** After connection we should change the parameters if we don't need fast response times.
 | 
				
			||||||
 | 
					         *  These settings are 150ms interval, 0 latency, 450ms timout. 
 | 
				
			||||||
 | 
					         *  Timeout should be a multiple of the interval, minimum is 100ms.
 | 
				
			||||||
 | 
					         *  I find a multiple of 3-5 * the interval works best for quick response/reconnect.
 | 
				
			||||||
 | 
					         *  Min interval: 120 * 1.25ms = 150, Max interval: 120 * 1.25ms = 150, 0 latency, 45 * 10ms = 450ms timeout 
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        pClient->updateConnParams(120,120,0,45);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void onDisconnect(NimBLEClient* pClient) {
 | 
				
			||||||
 | 
					        printf("%s Disconnected - Starting scan\n", pClient->getPeerAddress().toString().c_str());
 | 
				
			||||||
 | 
					        NimBLEDevice::getScan()->start(scanTime, scanEndedCB);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /********************* Security handled here **********************
 | 
				
			||||||
 | 
					    ****** Note: these are the same return values as defaults ********/
 | 
				
			||||||
 | 
					    uint32_t onPassKeyRequest(){
 | 
				
			||||||
 | 
					        printf("Client Passkey Request\n");
 | 
				
			||||||
 | 
					        /** return the passkey to send to the server */
 | 
				
			||||||
 | 
					        return 123456;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool onConfirmPIN(uint32_t pass_key){
 | 
				
			||||||
 | 
					        printf("The passkey YES/NO number: %d\n", pass_key);
 | 
				
			||||||
 | 
					    /** Return false if passkeys don't match. */
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** Pairing process complete, we can check the results in ble_gap_conn_desc */
 | 
				
			||||||
 | 
					    void onAuthenticationComplete(ble_gap_conn_desc* desc){
 | 
				
			||||||
 | 
					        if(!desc->sec_state.encrypted) {
 | 
				
			||||||
 | 
					            printf("Encrypt connection failed - disconnecting\n");
 | 
				
			||||||
 | 
					            /** Find the client with the connection handle provided in desc */
 | 
				
			||||||
 | 
					            NimBLEDevice::getClientByID(desc->conn_handle)->disconnect();
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Define a class to handle the callbacks when advertisments are received */
 | 
				
			||||||
 | 
					class AdvertisedDeviceCallbacks: public NimBLEAdvertisedDeviceCallbacks {
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    void onResult(NimBLEAdvertisedDevice* advertisedDevice) {
 | 
				
			||||||
 | 
					        printf("Advertised Device found: %s\n", advertisedDevice->toString().c_str());
 | 
				
			||||||
 | 
					        if(advertisedDevice->isAdvertisingService(NimBLEUUID("DEAD")))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            printf("Found Our Service\n");
 | 
				
			||||||
 | 
					            /** stop scan before connecting */
 | 
				
			||||||
 | 
					            NimBLEDevice::getScan()->stop();
 | 
				
			||||||
 | 
					            /** Save the device reference in a global for the client to use*/ 
 | 
				
			||||||
 | 
					            advDevice = advertisedDevice;
 | 
				
			||||||
 | 
					            /** Ready to connect now */ 
 | 
				
			||||||
 | 
					            doConnect = true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Notification / Indication receiving handler callback */
 | 
				
			||||||
 | 
					void notifyCB(NimBLERemoteCharacteristic* pRemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify){
 | 
				
			||||||
 | 
					    std::string str = (isNotify == true) ? "Notification" : "Indication"; 
 | 
				
			||||||
 | 
					    str += " from ";
 | 
				
			||||||
 | 
					    str += pRemoteCharacteristic->getRemoteService()->getClient()->getPeerAddress().toString();
 | 
				
			||||||
 | 
					    str += ": Service = " + pRemoteCharacteristic->getRemoteService()->getUUID().toString();
 | 
				
			||||||
 | 
					    str += ", Characteristic = " + pRemoteCharacteristic->getUUID().toString();
 | 
				
			||||||
 | 
					    str += ", Value = " + std::string((char*)pData, length);
 | 
				
			||||||
 | 
					    printf("%s\n", str.c_str());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Callback to process the results of the last scan or restart it */
 | 
				
			||||||
 | 
					void scanEndedCB(NimBLEScanResults results){
 | 
				
			||||||
 | 
					    printf("Scan Ended\n");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Create a single global instance of the callback class to be used by all clients */
 | 
				
			||||||
 | 
					static ClientCallbacks clientCB;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Handles the provisioning of clients and connects / interfaces with the server */
 | 
				
			||||||
 | 
					bool connectToServer() {
 | 
				
			||||||
 | 
					    NimBLEClient* pClient = nullptr;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /** Check if we have a client we should reuse first **/
 | 
				
			||||||
 | 
					    if(NimBLEDevice::getClientListSize()) {
 | 
				
			||||||
 | 
					        /** Special case when we already know this device, we send false as the 
 | 
				
			||||||
 | 
					         *  second argument in connect() to prevent refreshing the service database.
 | 
				
			||||||
 | 
					         *  This saves considerable time and power.
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        pClient = NimBLEDevice::getClientByPeerAddress(advDevice->getAddress());
 | 
				
			||||||
 | 
					        if(pClient){
 | 
				
			||||||
 | 
					            if(!pClient->connect(advDevice, false)) {
 | 
				
			||||||
 | 
					                printf("Reconnect failed\n");
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            printf("Reconnected client\n");
 | 
				
			||||||
 | 
					        } 
 | 
				
			||||||
 | 
					        /** We don't already have a client that knows this device,
 | 
				
			||||||
 | 
					         *  we will check for a client that is disconnected that we can use.
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        else {
 | 
				
			||||||
 | 
					            pClient = NimBLEDevice::getDisconnectedClient();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /** No client to reuse? Create a new one. */
 | 
				
			||||||
 | 
					    if(!pClient) {
 | 
				
			||||||
 | 
					        if(NimBLEDevice::getClientListSize() >= NIMBLE_MAX_CONNECTIONS) {
 | 
				
			||||||
 | 
					            printf("Max clients reached - no more connections available\n");
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        pClient = NimBLEDevice::createClient();
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        printf("New client created\n");
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					        pClient->setClientCallbacks(&clientCB, false);
 | 
				
			||||||
 | 
					        /** Set initial connection parameters: These settings are 15ms interval, 0 latency, 120ms timout. 
 | 
				
			||||||
 | 
					         *  These settings are safe for 3 clients to connect reliably, can go faster if you have less 
 | 
				
			||||||
 | 
					         *  connections. Timeout should be a multiple of the interval, minimum is 100ms.
 | 
				
			||||||
 | 
					         *  Min interval: 12 * 1.25ms = 15, Max interval: 12 * 1.25ms = 15, 0 latency, 12 * 10ms = 120ms timeout 
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        pClient->setConnectionParams(6,6,0,15);
 | 
				
			||||||
 | 
					        /** Set how long we are willing to wait for the connection to complete (seconds), default is 30. */
 | 
				
			||||||
 | 
					        pClient->setConnectTimeout(5);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!pClient->connect(advDevice)) {
 | 
				
			||||||
 | 
					            /** Created a client but failed to connect, don't need to keep it as it has no data */
 | 
				
			||||||
 | 
					            NimBLEDevice::deleteClient(pClient);
 | 
				
			||||||
 | 
					            printf("Failed to connect, deleted client\n");
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }         
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if(!pClient->isConnected()) {
 | 
				
			||||||
 | 
					        if (!pClient->connect(advDevice)) {
 | 
				
			||||||
 | 
					            printf("Failed to connect\n");
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    printf("Connected to: %s RSSI: %d\n", 
 | 
				
			||||||
 | 
					          pClient->getPeerAddress().toString().c_str(),
 | 
				
			||||||
 | 
					          pClient->getRssi());
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /** Now we can read/write/subscribe the charateristics of the services we are interested in */
 | 
				
			||||||
 | 
					    NimBLERemoteService* pSvc = nullptr;
 | 
				
			||||||
 | 
					    NimBLERemoteCharacteristic* pChr = nullptr;
 | 
				
			||||||
 | 
					    NimBLERemoteDescriptor* pDsc = nullptr;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    pSvc = pClient->getService("DEAD");
 | 
				
			||||||
 | 
					    if(pSvc) {     /** make sure it's not null */
 | 
				
			||||||
 | 
					        pChr = pSvc->getCharacteristic("BEEF");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(pChr) {     /** make sure it's not null */
 | 
				
			||||||
 | 
					        if(pChr->canRead()) {
 | 
				
			||||||
 | 
					            printf("%s Value: %s\n",
 | 
				
			||||||
 | 
					            pChr->getUUID().toString().c_str(),
 | 
				
			||||||
 | 
					            pChr->readValue().c_str());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        if(pChr->canWrite()) {
 | 
				
			||||||
 | 
					            if(pChr->writeValue("Tasty")) {
 | 
				
			||||||
 | 
					                printf("Wrote new value to: %s\n", pChr->getUUID().toString().c_str());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else {
 | 
				
			||||||
 | 
					                /** Disconnect if write failed */ 
 | 
				
			||||||
 | 
					                pClient->disconnect();
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            if(pChr->canRead()) {
 | 
				
			||||||
 | 
					                printf("The value of: %s is now: %s\n",
 | 
				
			||||||
 | 
					                       pChr->getUUID().toString().c_str(),
 | 
				
			||||||
 | 
					                       pChr->readValue().c_str());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        /** registerForNotify() has been deprecated and replaced with subscribe() / unsubscribe().
 | 
				
			||||||
 | 
					         *  Subscribe parameter defaults are: notifications=true, notifyCallback=nullptr, response=false.
 | 
				
			||||||
 | 
					         *  Unsubscribe parameter defaults are: response=false. 
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        if(pChr->canNotify()) {
 | 
				
			||||||
 | 
					            //if(!pChr->registerForNotify(notifyCB)) {
 | 
				
			||||||
 | 
					            if(!pChr->subscribe(true, notifyCB)) {
 | 
				
			||||||
 | 
					                /** Disconnect if subscribe failed */ 
 | 
				
			||||||
 | 
					                pClient->disconnect();
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else if(pChr->canIndicate()) {
 | 
				
			||||||
 | 
					            /** Send false as first argument to subscribe to indications instead of notifications */
 | 
				
			||||||
 | 
					            //if(!pChr->registerForNotify(notifyCB, false)) {
 | 
				
			||||||
 | 
					            if(!pChr->subscribe(false, notifyCB)) {
 | 
				
			||||||
 | 
					                /** Disconnect if subscribe failed */ 
 | 
				
			||||||
 | 
					                pClient->disconnect();
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    else{
 | 
				
			||||||
 | 
					        printf("DEAD service not found.\n");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    pSvc = pClient->getService("BAAD");
 | 
				
			||||||
 | 
					    if(pSvc) {     /** make sure it's not null */
 | 
				
			||||||
 | 
					        pChr = pSvc->getCharacteristic("F00D");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(pChr) {     /** make sure it's not null */
 | 
				
			||||||
 | 
					        if(pChr->canRead()) {
 | 
				
			||||||
 | 
					            printf("%s Value: %s\n",
 | 
				
			||||||
 | 
					            pChr->getUUID().toString().c_str(),
 | 
				
			||||||
 | 
					            pChr->readValue().c_str());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        pDsc = pChr->getDescriptor(NimBLEUUID("C01D"));
 | 
				
			||||||
 | 
					        if(pDsc) {   /** make sure it's not null */
 | 
				
			||||||
 | 
					            printf("Descriptor: %s  Value: %s\n",
 | 
				
			||||||
 | 
					                   pDsc->getUUID().toString().c_str(),
 | 
				
			||||||
 | 
					                   pDsc->readValue().c_str());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        if(pChr->canWrite()) {
 | 
				
			||||||
 | 
					            if(pChr->writeValue("No tip!")) {
 | 
				
			||||||
 | 
					                printf("Wrote new value to: %s\n", pChr->getUUID().toString().c_str());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else {
 | 
				
			||||||
 | 
					                /** Disconnect if write failed */ 
 | 
				
			||||||
 | 
					                pClient->disconnect();
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            if(pChr->canRead()) {
 | 
				
			||||||
 | 
					                printf("The value of: %s is now: %s\n",
 | 
				
			||||||
 | 
					                       pChr->getUUID().toString().c_str(),
 | 
				
			||||||
 | 
					                       pChr->readValue().c_str());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        /** registerForNotify() has been deprecated and replaced with subscribe() / unsubscribe().
 | 
				
			||||||
 | 
					         *  Subscribe parameter defaults are: notifications=true, notifyCallback=nullptr, response=false.
 | 
				
			||||||
 | 
					         *  Unsubscribe parameter defaults are: response=false. 
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        if(pChr->canNotify()) {
 | 
				
			||||||
 | 
					            //if(!pChr->registerForNotify(notifyCB)) {
 | 
				
			||||||
 | 
					            if(!pChr->subscribe(true, notifyCB)) {
 | 
				
			||||||
 | 
					                /** Disconnect if subscribe failed */ 
 | 
				
			||||||
 | 
					                pClient->disconnect();
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else if(pChr->canIndicate()) {
 | 
				
			||||||
 | 
					            /** Send false as first argument to subscribe to indications instead of notifications */
 | 
				
			||||||
 | 
					            //if(!pChr->registerForNotify(notifyCB, false)) {
 | 
				
			||||||
 | 
					            if(!pChr->subscribe(false, notifyCB)) {
 | 
				
			||||||
 | 
					                /** Disconnect if subscribe failed */ 
 | 
				
			||||||
 | 
					                pClient->disconnect();
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }    
 | 
				
			||||||
 | 
					    }        
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    else{
 | 
				
			||||||
 | 
					        printf("BAAD service not found.\n");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    printf("Done with this device!\n");
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void connectTask (void * parameter){
 | 
				
			||||||
 | 
					    /** Loop here until we find a device we want to connect to */
 | 
				
			||||||
 | 
					    for(;;) {
 | 
				
			||||||
 | 
					        if(doConnect) {
 | 
				
			||||||
 | 
					            doConnect = false;
 | 
				
			||||||
 | 
					            /** Found a device we want to connect to, do it now */
 | 
				
			||||||
 | 
					            if(connectToServer()) {
 | 
				
			||||||
 | 
					                printf("Success! we should now be getting notifications, scanning for more!\n");
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                printf("Failed to connect, starting scan\n");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					            NimBLEDevice::getScan()->start(scanTime,scanEndedCB);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        vTaskDelay(10/portTICK_PERIOD_MS);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    vTaskDelete(NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void app_main (void){
 | 
				
			||||||
 | 
					    printf("Starting NimBLE Client\n");
 | 
				
			||||||
 | 
					    /** Initialize NimBLE, no device name spcified as we are not advertising */
 | 
				
			||||||
 | 
					    NimBLEDevice::init("");
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /** Set the IO capabilities of the device, each option will trigger a different pairing method.
 | 
				
			||||||
 | 
					     *  BLE_HS_IO_KEYBOARD_ONLY    - Passkey pairing
 | 
				
			||||||
 | 
					     *  BLE_HS_IO_DISPLAY_YESNO   - Numeric comparison pairing
 | 
				
			||||||
 | 
					     *  BLE_HS_IO_NO_INPUT_OUTPUT - DEFAULT setting - just works pairing
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    //NimBLEDevice::setSecurityIOCap(BLE_HS_IO_KEYBOARD_ONLY); // use passkey
 | 
				
			||||||
 | 
					    //NimBLEDevice::setSecurityIOCap(BLE_HS_IO_DISPLAY_YESNO); //use numeric comparison
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					    /** 2 different ways to set security - both calls achieve the same result.
 | 
				
			||||||
 | 
					     *  no bonding, no man in the middle protection, secure connections.
 | 
				
			||||||
 | 
					     *     
 | 
				
			||||||
 | 
					     *  These are the default values, only shown here for demonstration.   
 | 
				
			||||||
 | 
					     */ 
 | 
				
			||||||
 | 
					    //NimBLEDevice::setSecurityAuth(false, false, true); 
 | 
				
			||||||
 | 
					    NimBLEDevice::setSecurityAuth(/*BLE_SM_PAIR_AUTHREQ_BOND | BLE_SM_PAIR_AUTHREQ_MITM |*/ BLE_SM_PAIR_AUTHREQ_SC);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					    /** Optional: set the transmit power, default is -3db */
 | 
				
			||||||
 | 
					    NimBLEDevice::setPower(ESP_PWR_LVL_P9); /** 12db */
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /** Optional: set any devices you don't want to get advertisments from */
 | 
				
			||||||
 | 
					    // NimBLEDevice::addIgnored(NimBLEAddress ("aa:bb:cc:dd:ee:ff")); 
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					    /** create new scan */  
 | 
				
			||||||
 | 
					    NimBLEScan* pScan = NimBLEDevice::getScan(); 
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /** create a callback that gets called when advertisers are found */
 | 
				
			||||||
 | 
					    pScan->setAdvertisedDeviceCallbacks(new AdvertisedDeviceCallbacks());
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /** Set scan interval (how often) and window (how long) in milliseconds */
 | 
				
			||||||
 | 
					    pScan->setInterval(400);
 | 
				
			||||||
 | 
					    pScan->setWindow(100);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /** Active scan will gather scan response data from advertisers
 | 
				
			||||||
 | 
					     *  but will use more energy from both devices
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    pScan->setActiveScan(true);
 | 
				
			||||||
 | 
					    /** Start scanning for advertisers for the scan time specified (in seconds) 0 = forever
 | 
				
			||||||
 | 
					     *  Optional callback for when scanning stops. 
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    pScan->start(scanTime, scanEndedCB);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    printf("Scanning for peripherals\n");
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    xTaskCreate(connectTask, "connectTask", 5000, NULL, 1, NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					# The following lines of boilerplate have to be in your project's
 | 
				
			||||||
 | 
					# CMakeLists in this exact order for cmake to work correctly
 | 
				
			||||||
 | 
					cmake_minimum_required(VERSION 3.5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include($ENV{IDF_PATH}/tools/cmake/project.cmake)
 | 
				
			||||||
 | 
					set(SUPPORTED_TARGETS esp32)
 | 
				
			||||||
 | 
					project(NimBLE_Server)
 | 
				
			||||||
@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					PROJECT_NAME := NimBLE_Server
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include $(IDF_PATH)/make/project.mk
 | 
				
			||||||
@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					set(COMPONENT_SRCS "main.cpp")
 | 
				
			||||||
 | 
					set(COMPONENT_ADD_INCLUDEDIRS ".")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					register_component()
 | 
				
			||||||
@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					#
 | 
				
			||||||
 | 
					# "main" pseudo-component makefile.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
 | 
				
			||||||
@@ -0,0 +1,229 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					/** NimBLE_Server Demo:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Demonstrates many of the available features of the NimBLE server library.
 | 
				
			||||||
 | 
					 *  
 | 
				
			||||||
 | 
					 *  Created: on March 22 2020
 | 
				
			||||||
 | 
					 *      Author: H2zero
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					#include "NimBLEDevice.h"
 | 
				
			||||||
 | 
					#include "NimBLELog.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern "C" {void app_main(void);}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static NimBLEServer* pServer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**  None of these are required as they will be handled by the library with defaults. **
 | 
				
			||||||
 | 
					 **                       Remove as you see fit for your needs                        */  
 | 
				
			||||||
 | 
					class ServerCallbacks: public NimBLEServerCallbacks {
 | 
				
			||||||
 | 
					    void onConnect(NimBLEServer* pServer) {
 | 
				
			||||||
 | 
					        printf("Client connected\n");
 | 
				
			||||||
 | 
					        NimBLEDevice::startAdvertising();
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    /** Alternative onConnect() method to extract details of the connection. 
 | 
				
			||||||
 | 
					     *  See: src/ble_gap.h for the details of the ble_gap_conn_desc struct.
 | 
				
			||||||
 | 
					     */  
 | 
				
			||||||
 | 
					    void onConnect(NimBLEServer* pServer, ble_gap_conn_desc* desc) {
 | 
				
			||||||
 | 
					        printf("Client address: %s\n", NimBLEAddress(desc->peer_ota_addr).toString().c_str());
 | 
				
			||||||
 | 
					        /** We can use the connection handle here to ask for different connection parameters.
 | 
				
			||||||
 | 
					         *  Args: connection handle, min connection interval, max connection interval
 | 
				
			||||||
 | 
					         *  latency, supervision timeout.
 | 
				
			||||||
 | 
					         *  Units; Min/Max Intervals: 1.25 millisecond increments.
 | 
				
			||||||
 | 
					         *  Latency: number of intervals allowed to skip.
 | 
				
			||||||
 | 
					         *  Timeout: 10 millisecond increments, try for 3x interval time for best results.  
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        pServer->updateConnParams(desc->conn_handle, 24, 48, 0, 18);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    void onDisconnect(NimBLEServer* pServer) {
 | 
				
			||||||
 | 
					        printf("Client disconnected - start advertising\n");
 | 
				
			||||||
 | 
					        NimBLEDevice::startAdvertising();
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    void onMTUChange(uint16_t MTU, ble_gap_conn_desc* desc) {
 | 
				
			||||||
 | 
					        printf("MTU updated: %u for connection ID: %u\n", MTU, desc->conn_handle);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					/********************* Security handled here **********************
 | 
				
			||||||
 | 
					****** Note: these are the same return values as defaults ********/
 | 
				
			||||||
 | 
					    uint32_t onPassKeyRequest(){
 | 
				
			||||||
 | 
					        printf("Server Passkey Request\n");
 | 
				
			||||||
 | 
					        /** This should return a random 6 digit number for security 
 | 
				
			||||||
 | 
					         *  or make your own static passkey as done here.
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        return 123456; 
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool onConfirmPIN(uint32_t pass_key){
 | 
				
			||||||
 | 
					        printf("The passkey YES/NO number: %d\n", pass_key);
 | 
				
			||||||
 | 
					        /** Return false if passkeys don't match. */
 | 
				
			||||||
 | 
					        return true; 
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void onAuthenticationComplete(ble_gap_conn_desc* desc){
 | 
				
			||||||
 | 
					        /** Check that encryption was successful, if not we disconnect the client */  
 | 
				
			||||||
 | 
					        if(!desc->sec_state.encrypted) {
 | 
				
			||||||
 | 
					            /** NOTE: createServer returns the current server reference unless one is not already created */
 | 
				
			||||||
 | 
					            NimBLEDevice::createServer()->disconnect(desc->conn_handle);
 | 
				
			||||||
 | 
					            printf("Encrypt connection failed - disconnecting client\n");
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        printf("Starting BLE work!");
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Handler class for characteristic actions */
 | 
				
			||||||
 | 
					class CharacteristicCallbacks: public NimBLECharacteristicCallbacks {
 | 
				
			||||||
 | 
					    void onRead(NimBLECharacteristic* pCharacteristic){
 | 
				
			||||||
 | 
					        printf("%s : onRead(), value: %s\n", 
 | 
				
			||||||
 | 
					                            pCharacteristic->getUUID().toString().c_str(),
 | 
				
			||||||
 | 
					                            pCharacteristic->getValue().c_str());
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void onWrite(NimBLECharacteristic* pCharacteristic) {
 | 
				
			||||||
 | 
					        printf("%s : onWrite(), value: %s\n", 
 | 
				
			||||||
 | 
					                            pCharacteristic->getUUID().toString().c_str(),
 | 
				
			||||||
 | 
					                            pCharacteristic->getValue().c_str());
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    /** Called before notification or indication is sent, 
 | 
				
			||||||
 | 
					     *  the value can be changed here before sending if desired.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    void onNotify(NimBLECharacteristic* pCharacteristic) {
 | 
				
			||||||
 | 
					        printf("Sending notification to clients\n");
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** The status returned in status is defined in NimBLECharacteristic.h.
 | 
				
			||||||
 | 
					     *  The value returned in code is the NimBLE host return code.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    void onStatus(NimBLECharacteristic* pCharacteristic, Status status, int code) {
 | 
				
			||||||
 | 
					        printf("Notification/Indication status code: %d , return code: %d, %s\n",
 | 
				
			||||||
 | 
					                            status,
 | 
				
			||||||
 | 
					                            code,
 | 
				
			||||||
 | 
					                            NimBLEUtils::returnCodeToString(code));
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					/** Handler class for descriptor actions */    
 | 
				
			||||||
 | 
					class DescriptorCallbacks : public NimBLEDescriptorCallbacks {
 | 
				
			||||||
 | 
					    void onWrite(NimBLEDescriptor* pDescriptor) {
 | 
				
			||||||
 | 
					        std::string dscVal((char*)pDescriptor->getValue(), pDescriptor->getLength());
 | 
				
			||||||
 | 
					        printf("Descriptor witten value: %s\n", dscVal.c_str());
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void onRead(NimBLEDescriptor* pDescriptor) {
 | 
				
			||||||
 | 
					        printf("%s Descriptor read\n", pDescriptor->getUUID().toString().c_str());
 | 
				
			||||||
 | 
					    };;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Define callback instances globally to use for multiple Charateristics \ Descriptors */ 
 | 
				
			||||||
 | 
					static DescriptorCallbacks dscCallbacks;
 | 
				
			||||||
 | 
					static CharacteristicCallbacks chrCallbacks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void notifyTask(void * parameter){
 | 
				
			||||||
 | 
					    for(;;) {
 | 
				
			||||||
 | 
					        if(pServer->getConnectedCount()) {
 | 
				
			||||||
 | 
					            NimBLEService* pSvc = pServer->getServiceByUUID("BAAD");
 | 
				
			||||||
 | 
					            if(pSvc) {
 | 
				
			||||||
 | 
					                NimBLECharacteristic* pChr = pSvc->getCharacteristic("F00D");
 | 
				
			||||||
 | 
					                if(pChr) {
 | 
				
			||||||
 | 
					                    pChr->notify(true);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        vTaskDelay(2000/portTICK_PERIOD_MS);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    vTaskDelete(NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void app_main(void) {
 | 
				
			||||||
 | 
					    printf("Starting NimBLE Server\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** sets device name */
 | 
				
			||||||
 | 
					    NimBLEDevice::init("NimBLE");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** Set the IO capabilities of the device, each option will trigger a different pairing method.
 | 
				
			||||||
 | 
					     *  BLE_HS_IO_DISPLAY_ONLY    - Passkey pairing
 | 
				
			||||||
 | 
					     *  BLE_HS_IO_DISPLAY_YESNO   - Numeric comparison pairing
 | 
				
			||||||
 | 
					     *  BLE_HS_IO_NO_INPUT_OUTPUT - DEFAULT setting - just works pairing
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    //NimBLEDevice::setSecurityIOCap(BLE_HS_IO_DISPLAY_ONLY); // use passkey
 | 
				
			||||||
 | 
					    //NimBLEDevice::setSecurityIOCap(BLE_HS_IO_DISPLAY_YESNO); //use numeric comparison
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** 2 different ways to set security - both calls achieve the same result.
 | 
				
			||||||
 | 
					     *  no bonding, no man in the middle protection, secure connections.
 | 
				
			||||||
 | 
					     *   
 | 
				
			||||||
 | 
					     *  These are the default values, only shown here for demonstration.   
 | 
				
			||||||
 | 
					     */ 
 | 
				
			||||||
 | 
					    //NimBLEDevice::setSecurityAuth(false, false, true); 
 | 
				
			||||||
 | 
					    NimBLEDevice::setSecurityAuth(/*BLE_SM_PAIR_AUTHREQ_BOND | BLE_SM_PAIR_AUTHREQ_MITM |*/ BLE_SM_PAIR_AUTHREQ_SC);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pServer = NimBLEDevice::createServer();
 | 
				
			||||||
 | 
					    pServer->setCallbacks(new ServerCallbacks());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NimBLEService* pDeadService = pServer->createService("DEAD");
 | 
				
			||||||
 | 
					    NimBLECharacteristic* pBeefCharacteristic = pDeadService->createCharacteristic(
 | 
				
			||||||
 | 
					                                               "BEEF",
 | 
				
			||||||
 | 
					                                               NIMBLE_PROPERTY::READ |
 | 
				
			||||||
 | 
					                                               NIMBLE_PROPERTY::WRITE |
 | 
				
			||||||
 | 
					                               /** Require a secure connection for read and write access */
 | 
				
			||||||
 | 
					                                               NIMBLE_PROPERTY::READ_ENC |  // only allow reading if paired / encrypted
 | 
				
			||||||
 | 
					                                               NIMBLE_PROPERTY::WRITE_ENC   // only allow writing if paired / encrypted
 | 
				
			||||||
 | 
					                                              );
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					    pBeefCharacteristic->setValue("Burger");
 | 
				
			||||||
 | 
					    pBeefCharacteristic->setCallbacks(&chrCallbacks);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** 2902 and 2904 descriptors are a special case, when createDescriptor is called with
 | 
				
			||||||
 | 
					     *  either of those uuid's it will create the associated class with the correct properties
 | 
				
			||||||
 | 
					     *  and sizes. However we must cast the returned reference to the correct type as the method
 | 
				
			||||||
 | 
					     *  only returns a pointer to the base NimBLEDescriptor class.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    NimBLE2904* pBeef2904 = (NimBLE2904*)pBeefCharacteristic->createDescriptor("2904"); 
 | 
				
			||||||
 | 
					    pBeef2904->setFormat(NimBLE2904::FORMAT_UTF8);
 | 
				
			||||||
 | 
					    pBeef2904->setCallbacks(&dscCallbacks);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NimBLEService* pBaadService = pServer->createService("BAAD");
 | 
				
			||||||
 | 
					    NimBLECharacteristic* pFoodCharacteristic = pBaadService->createCharacteristic(
 | 
				
			||||||
 | 
					                                               "F00D",
 | 
				
			||||||
 | 
					                                               NIMBLE_PROPERTY::READ |
 | 
				
			||||||
 | 
					                                               NIMBLE_PROPERTY::WRITE |
 | 
				
			||||||
 | 
					                                               NIMBLE_PROPERTY::NOTIFY
 | 
				
			||||||
 | 
					                                              );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pFoodCharacteristic->setValue("Fries");
 | 
				
			||||||
 | 
					    pFoodCharacteristic->setCallbacks(&chrCallbacks);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** Custom descriptor: Arguments are UUID, Properties, max length in bytes of the value */
 | 
				
			||||||
 | 
					    NimBLEDescriptor* pC01Ddsc = pFoodCharacteristic->createDescriptor(
 | 
				
			||||||
 | 
					                                               "C01D",
 | 
				
			||||||
 | 
					                                               NIMBLE_PROPERTY::READ | 
 | 
				
			||||||
 | 
					                                               NIMBLE_PROPERTY::WRITE|
 | 
				
			||||||
 | 
					                                               NIMBLE_PROPERTY::WRITE_ENC, // only allow writing if paired / encrypted
 | 
				
			||||||
 | 
					                                               20
 | 
				
			||||||
 | 
					                                              );
 | 
				
			||||||
 | 
					    pC01Ddsc->setValue("Send it back!");
 | 
				
			||||||
 | 
					    pC01Ddsc->setCallbacks(&dscCallbacks);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** Start the services when finished creating all Characteristics and Descriptors */  
 | 
				
			||||||
 | 
					    pDeadService->start();
 | 
				
			||||||
 | 
					    pBaadService->start();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NimBLEAdvertising* pAdvertising = NimBLEDevice::getAdvertising();
 | 
				
			||||||
 | 
					    /** Add the services to the advertisment data **/
 | 
				
			||||||
 | 
					    pAdvertising->addServiceUUID(pDeadService->getUUID());
 | 
				
			||||||
 | 
					    pAdvertising->addServiceUUID(pBaadService->getUUID());
 | 
				
			||||||
 | 
					    /** If your device is battery powered you may consider setting scan response
 | 
				
			||||||
 | 
					     *  to false as it will extend battery life at the expense of less data sent.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    pAdvertising->setScanResponse(true);
 | 
				
			||||||
 | 
					    pAdvertising->start();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    printf("Advertising Started\n");
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    xTaskCreate(notifyTask, "notifyTask", 5000, NULL, 1, NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					# The following lines of boilerplate have to be in your project's
 | 
				
			||||||
 | 
					# CMakeLists in this exact order for cmake to work correctly
 | 
				
			||||||
 | 
					cmake_minimum_required(VERSION 3.5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include($ENV{IDF_PATH}/tools/cmake/project.cmake)
 | 
				
			||||||
 | 
					set(SUPPORTED_TARGETS esp32)
 | 
				
			||||||
 | 
					project(BLE_client)
 | 
				
			||||||
@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					PROJECT_NAME := BLE_client
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include $(IDF_PATH)/make/project.mk
 | 
				
			||||||
@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					set(COMPONENT_SRCS "main.cpp")
 | 
				
			||||||
 | 
					set(COMPONENT_ADD_INCLUDEDIRS ".")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					register_component()
 | 
				
			||||||
@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					#
 | 
				
			||||||
 | 
					# "main" pseudo-component makefile.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
 | 
				
			||||||
@@ -0,0 +1,200 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * A BLE client example that is rich in capabilities.
 | 
				
			||||||
 | 
					 * There is a lot new capabilities implemented.
 | 
				
			||||||
 | 
					 * author unknown
 | 
				
			||||||
 | 
					 * updated by chegewara
 | 
				
			||||||
 | 
					 * updated for NimBLE by H2zero
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					/** NimBLE differences highlighted in comment blocks **/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******original********
 | 
				
			||||||
 | 
					#include "BLEDevice.h"
 | 
				
			||||||
 | 
					***********************/
 | 
				
			||||||
 | 
					#include "NimBLEDevice.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern "C"{void app_main(void);}
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					// The remote service we wish to connect to.
 | 
				
			||||||
 | 
					static BLEUUID serviceUUID("4fafc201-1fb5-459e-8fcc-c5c9c331914b");
 | 
				
			||||||
 | 
					// The characteristic of the remote service we are interested in.
 | 
				
			||||||
 | 
					static BLEUUID    charUUID("beb5483e-36e1-4688-b7f5-ea07361b26a8");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool doConnect = false;
 | 
				
			||||||
 | 
					static bool connected = false;
 | 
				
			||||||
 | 
					static bool doScan = false;
 | 
				
			||||||
 | 
					static BLERemoteCharacteristic* pRemoteCharacteristic;
 | 
				
			||||||
 | 
					static BLEAdvertisedDevice* myDevice;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void notifyCallback(
 | 
				
			||||||
 | 
					  BLERemoteCharacteristic* pBLERemoteCharacteristic,
 | 
				
			||||||
 | 
					  uint8_t* pData,
 | 
				
			||||||
 | 
					  size_t length,
 | 
				
			||||||
 | 
					  bool isNotify) {
 | 
				
			||||||
 | 
					    printf("Notify callback for characteristic %s of data length %d data: %s\n",
 | 
				
			||||||
 | 
					           pBLERemoteCharacteristic->getUUID().toString().c_str(),
 | 
				
			||||||
 | 
					           length,
 | 
				
			||||||
 | 
					           (char*)pData);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**  None of these are required as they will be handled by the library with defaults. **
 | 
				
			||||||
 | 
					 **                       Remove as you see fit for your needs                        */  
 | 
				
			||||||
 | 
					class MyClientCallback : public BLEClientCallbacks {
 | 
				
			||||||
 | 
					  void onConnect(BLEClient* pclient) {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void onDisconnect(BLEClient* pclient) {
 | 
				
			||||||
 | 
					    connected = false;
 | 
				
			||||||
 | 
					    printf("onDisconnect");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					/***************** New - Security handled here ********************
 | 
				
			||||||
 | 
					****** Note: these are the same return values as defaults ********/
 | 
				
			||||||
 | 
					  uint32_t onPassKeyRequest(){
 | 
				
			||||||
 | 
					    printf("Client PassKeyRequest\n");
 | 
				
			||||||
 | 
					    return 123456; 
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  bool onConfirmPIN(uint32_t pass_key){
 | 
				
			||||||
 | 
					    printf("The passkey YES/NO number: %d\n", pass_key);
 | 
				
			||||||
 | 
					    return true; 
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void onAuthenticationComplete(ble_gap_conn_desc desc){
 | 
				
			||||||
 | 
					    printf("Starting BLE work!\n");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					/*******************************************************************/
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool connectToServer() {
 | 
				
			||||||
 | 
					    printf("Forming a connection to %s\n", myDevice->getAddress().toString().c_str());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    BLEClient*  pClient  = BLEDevice::createClient();
 | 
				
			||||||
 | 
					    printf(" - Created client\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pClient->setClientCallbacks(new MyClientCallback());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Connect to the remove BLE Server.
 | 
				
			||||||
 | 
					    pClient->connect(myDevice);  // if you pass BLEAdvertisedDevice instead of address, it will be recognized type of peer device address (public or private)
 | 
				
			||||||
 | 
					    printf(" - Connected to server\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Obtain a reference to the service we are after in the remote BLE server.
 | 
				
			||||||
 | 
					    BLERemoteService* pRemoteService = pClient->getService(serviceUUID);
 | 
				
			||||||
 | 
					    if (pRemoteService == nullptr) {
 | 
				
			||||||
 | 
					      printf("Failed to find our service UUID: %s\n", serviceUUID.toString().c_str());
 | 
				
			||||||
 | 
					      pClient->disconnect();
 | 
				
			||||||
 | 
					      return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    printf(" - Found our service\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Obtain a reference to the characteristic in the service of the remote BLE server.
 | 
				
			||||||
 | 
					    pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID);
 | 
				
			||||||
 | 
					    if (pRemoteCharacteristic == nullptr) {
 | 
				
			||||||
 | 
					      printf("Failed to find our characteristic UUID: %s\n", charUUID.toString().c_str());
 | 
				
			||||||
 | 
					      pClient->disconnect();
 | 
				
			||||||
 | 
					      return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    printf(" - Found our characteristic\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Read the value of the characteristic.
 | 
				
			||||||
 | 
					    if(pRemoteCharacteristic->canRead()) {
 | 
				
			||||||
 | 
					      std::string value = pRemoteCharacteristic->readValue();
 | 
				
			||||||
 | 
					      printf("The characteristic value was: %s\n", value.c_str());
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    /** registerForNotify() has been deprecated and replaced with subscribe() / unsubscribe().
 | 
				
			||||||
 | 
					     *  Subscribe parameter defaults are: notifications=true, notifyCallback=nullptr, response=false.
 | 
				
			||||||
 | 
					     *  Unsubscribe parameter defaults are: response=false. 
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    if(pRemoteCharacteristic->canNotify()) {
 | 
				
			||||||
 | 
					        //pRemoteCharacteristic->registerForNotify(notifyCallback);
 | 
				
			||||||
 | 
					        pRemoteCharacteristic->subscribe(true, notifyCallback);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    connected = true;
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Scan for BLE servers and find the first one that advertises the service we are looking for.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
 | 
				
			||||||
 | 
					 /**
 | 
				
			||||||
 | 
					   * Called for each advertising BLE server.
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					   
 | 
				
			||||||
 | 
					/*** Only a reference to the advertised device is passed now
 | 
				
			||||||
 | 
					  void onResult(BLEAdvertisedDevice advertisedDevice) { **/     
 | 
				
			||||||
 | 
					  void onResult(BLEAdvertisedDevice* advertisedDevice) {
 | 
				
			||||||
 | 
					    printf("BLE Advertised Device found: %s\n", advertisedDevice->toString().c_str());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // We have found a device, let us now see if it contains the service we are looking for.
 | 
				
			||||||
 | 
					/********************************************************************************
 | 
				
			||||||
 | 
					    if (advertisedDevice.haveServiceUUID() && advertisedDevice.isAdvertisingService(serviceUUID)) {
 | 
				
			||||||
 | 
					********************************************************************************/
 | 
				
			||||||
 | 
					    if (advertisedDevice->haveServiceUUID() && advertisedDevice->isAdvertisingService(serviceUUID)) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      BLEDevice::getScan()->stop();
 | 
				
			||||||
 | 
					/*******************************************************************
 | 
				
			||||||
 | 
					      myDevice = new BLEAdvertisedDevice(advertisedDevice);
 | 
				
			||||||
 | 
					*******************************************************************/
 | 
				
			||||||
 | 
					      myDevice = advertisedDevice; /** Just save the reference now, no need to copy the object */
 | 
				
			||||||
 | 
					      doConnect = true;
 | 
				
			||||||
 | 
					      doScan = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    } // Found our server
 | 
				
			||||||
 | 
					  } // onResult
 | 
				
			||||||
 | 
					}; // MyAdvertisedDeviceCallbacks
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// This is the Arduino main loop function.
 | 
				
			||||||
 | 
					void connectTask (void * parameter){
 | 
				
			||||||
 | 
					    for(;;) {
 | 
				
			||||||
 | 
					      // If the flag "doConnect" is true then we have scanned for and found the desired
 | 
				
			||||||
 | 
					      // BLE Server with which we wish to connect.  Now we connect to it.  Once we are 
 | 
				
			||||||
 | 
					      // connected we set the connected flag to be true.
 | 
				
			||||||
 | 
					      if (doConnect == true) {
 | 
				
			||||||
 | 
					        if (connectToServer()) {
 | 
				
			||||||
 | 
					          printf("We are now connected to the BLE Server.\n");
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          printf("We have failed to connect to the server; there is nothin more we will do.\n");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        doConnect = false;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // If we are connected to a peer BLE Server, update the characteristic each time we are reached
 | 
				
			||||||
 | 
					      // with the current time since boot.
 | 
				
			||||||
 | 
					      if (connected) {
 | 
				
			||||||
 | 
					        char buf[256];
 | 
				
			||||||
 | 
					        snprintf(buf, 256, "Time since boot: %lu", (unsigned long)(esp_timer_get_time() / 1000000ULL));
 | 
				
			||||||
 | 
					        printf("Setting new characteristic value to %s\n", buf);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        // Set the characteristic's value to be the array of bytes that is actually a string.
 | 
				
			||||||
 | 
					        /*** Note: write value now returns true if successful, false otherwise - try again or disconnect ***/
 | 
				
			||||||
 | 
					        pRemoteCharacteristic->writeValue((uint8_t*)buf, strlen(buf), false);
 | 
				
			||||||
 | 
					      }else if(doScan){
 | 
				
			||||||
 | 
					        BLEDevice::getScan()->start(0);  // this is just eample to start scan after disconnect, most likely there is better way to do it in arduino
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      vTaskDelay(1000/portTICK_PERIOD_MS); // Delay a second between loops.
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    vTaskDelete(NULL);
 | 
				
			||||||
 | 
					} // End of loop
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void app_main(void) {
 | 
				
			||||||
 | 
					  printf("Starting BLE Client application...\n");
 | 
				
			||||||
 | 
					  BLEDevice::init("");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Retrieve a Scanner and set the callback we want to use to be informed when we
 | 
				
			||||||
 | 
					  // have detected a new device.  Specify that we want active scanning and start the
 | 
				
			||||||
 | 
					  // scan to run for 5 seconds.
 | 
				
			||||||
 | 
					  BLEScan* pBLEScan = BLEDevice::getScan();
 | 
				
			||||||
 | 
					  pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
 | 
				
			||||||
 | 
					  pBLEScan->setInterval(1349);
 | 
				
			||||||
 | 
					  pBLEScan->setWindow(449);
 | 
				
			||||||
 | 
					  pBLEScan->setActiveScan(true);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  xTaskCreate(connectTask, "connectTask", 5000, NULL, 1, NULL);
 | 
				
			||||||
 | 
					  pBLEScan->start(5, false);
 | 
				
			||||||
 | 
					} // End of setup.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					# The following lines of boilerplate have to be in your project's
 | 
				
			||||||
 | 
					# CMakeLists in this exact order for cmake to work correctly
 | 
				
			||||||
 | 
					cmake_minimum_required(VERSION 3.5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include($ENV{IDF_PATH}/tools/cmake/project.cmake)
 | 
				
			||||||
 | 
					set(SUPPORTED_TARGETS esp32)
 | 
				
			||||||
 | 
					project(BLE_notify)
 | 
				
			||||||
@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					PROJECT_NAME := BLE_notify
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include $(IDF_PATH)/make/project.mk
 | 
				
			||||||
@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					set(COMPONENT_SRCS "main.cpp")
 | 
				
			||||||
 | 
					set(COMPONENT_ADD_INCLUDEDIRS ".")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					register_component()
 | 
				
			||||||
@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					#
 | 
				
			||||||
 | 
					# "main" pseudo-component makefile.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
 | 
				
			||||||
@@ -0,0 +1,155 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					    Video: https://www.youtube.com/watch?v=oCMOYS71NIU
 | 
				
			||||||
 | 
					    Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleNotify.cpp
 | 
				
			||||||
 | 
					    Ported to Arduino ESP32 by Evandro Copercini
 | 
				
			||||||
 | 
					    updated by chegewara
 | 
				
			||||||
 | 
					    Refactored back to IDF by H2zero
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   Create a BLE server that, once we receive a connection, will send periodic notifications.
 | 
				
			||||||
 | 
					   The service advertises itself as: 4fafc201-1fb5-459e-8fcc-c5c9c331914b
 | 
				
			||||||
 | 
					   And has a characteristic of: beb5483e-36e1-4688-b7f5-ea07361b26a8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   The design of creating the BLE server is:
 | 
				
			||||||
 | 
					   1. Create a BLE Server
 | 
				
			||||||
 | 
					   2. Create a BLE Service
 | 
				
			||||||
 | 
					   3. Create a BLE Characteristic on the Service
 | 
				
			||||||
 | 
					   4. Create a BLE Descriptor on the characteristic
 | 
				
			||||||
 | 
					   5. Start the service.
 | 
				
			||||||
 | 
					   6. Start advertising.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   A connect hander associated with the server starts a background task that performs notification
 | 
				
			||||||
 | 
					   every couple of seconds.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** NimBLE differences highlighted in comment blocks **/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******original********
 | 
				
			||||||
 | 
					#include <BLEDevice.h>
 | 
				
			||||||
 | 
					#include <BLEServer.h>
 | 
				
			||||||
 | 
					#include <BLEUtils.h>
 | 
				
			||||||
 | 
					#include <BLE2902.h>
 | 
				
			||||||
 | 
					***********************/
 | 
				
			||||||
 | 
					#include <NimBLEDevice.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern "C" {void app_main(void);}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BLEServer* pServer = NULL;
 | 
				
			||||||
 | 
					BLECharacteristic* pCharacteristic = NULL;
 | 
				
			||||||
 | 
					bool deviceConnected = false;
 | 
				
			||||||
 | 
					bool oldDeviceConnected = false;
 | 
				
			||||||
 | 
					uint32_t value = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// See the following for generating UUIDs:
 | 
				
			||||||
 | 
					// https://www.uuidgenerator.net/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SERVICE_UUID        "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
 | 
				
			||||||
 | 
					#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**  None of these are required as they will be handled by the library with defaults. **
 | 
				
			||||||
 | 
					 **                       Remove as you see fit for your needs                        */  
 | 
				
			||||||
 | 
					class MyServerCallbacks: public BLEServerCallbacks {
 | 
				
			||||||
 | 
					    void onConnect(BLEServer* pServer) {
 | 
				
			||||||
 | 
					      deviceConnected = true;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void onDisconnect(BLEServer* pServer) {
 | 
				
			||||||
 | 
					      deviceConnected = false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					/***************** New - Security handled here ********************
 | 
				
			||||||
 | 
					****** Note: these are the same return values as defaults ********/
 | 
				
			||||||
 | 
					  uint32_t onPassKeyRequest(){
 | 
				
			||||||
 | 
					    printf("Server PassKeyRequest\n");
 | 
				
			||||||
 | 
					    return 123456; 
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool onConfirmPIN(uint32_t pass_key){
 | 
				
			||||||
 | 
					    printf("The passkey YES/NO number: %d\n", pass_key);
 | 
				
			||||||
 | 
					    return true; 
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void onAuthenticationComplete(ble_gap_conn_desc desc){
 | 
				
			||||||
 | 
					    printf("Starting BLE work!\n");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					/*******************************************************************/
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void connectedTask (void * parameter){
 | 
				
			||||||
 | 
					    for(;;) {
 | 
				
			||||||
 | 
					        // notify changed value
 | 
				
			||||||
 | 
					        if (deviceConnected) {
 | 
				
			||||||
 | 
					            pCharacteristic->setValue((uint8_t*)&value, 4);
 | 
				
			||||||
 | 
					            pCharacteristic->notify();
 | 
				
			||||||
 | 
					            value++;
 | 
				
			||||||
 | 
					            vTaskDelay(100/portTICK_PERIOD_MS);  // bluetooth stack will go into congestion, if too many packets are sent
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // disconnecting
 | 
				
			||||||
 | 
					        if (!deviceConnected && oldDeviceConnected) {
 | 
				
			||||||
 | 
					            vTaskDelay(500/portTICK_PERIOD_MS); // give the bluetooth stack the chance to get things ready
 | 
				
			||||||
 | 
					            pServer->startAdvertising(); // restart advertising
 | 
				
			||||||
 | 
					            printf("start advertising\n");
 | 
				
			||||||
 | 
					            oldDeviceConnected = deviceConnected;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // connecting
 | 
				
			||||||
 | 
					        if (deviceConnected && !oldDeviceConnected) {
 | 
				
			||||||
 | 
					            // do stuff here on connecting
 | 
				
			||||||
 | 
					            oldDeviceConnected = deviceConnected;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        vTaskDelay(10/portTICK_PERIOD_MS); // Delay between loops to reset watchdog timer
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    vTaskDelete(NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					void app_main(void) {
 | 
				
			||||||
 | 
					  // Create the BLE Device
 | 
				
			||||||
 | 
					  BLEDevice::init("ESP32");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Create the BLE Server
 | 
				
			||||||
 | 
					  pServer = BLEDevice::createServer();
 | 
				
			||||||
 | 
					  pServer->setCallbacks(new MyServerCallbacks());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Create the BLE Service
 | 
				
			||||||
 | 
					  BLEService *pService = pServer->createService(SERVICE_UUID);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Create a BLE Characteristic
 | 
				
			||||||
 | 
					  pCharacteristic = pService->createCharacteristic(
 | 
				
			||||||
 | 
					                      CHARACTERISTIC_UUID,
 | 
				
			||||||
 | 
					                /******* Enum Type NIMBLE_PROPERTY now *******     
 | 
				
			||||||
 | 
					                      BLECharacteristic::PROPERTY_READ   |
 | 
				
			||||||
 | 
					                      BLECharacteristic::PROPERTY_WRITE  |
 | 
				
			||||||
 | 
					                      BLECharacteristic::PROPERTY_NOTIFY |
 | 
				
			||||||
 | 
					                      BLECharacteristic::PROPERTY_INDICATE
 | 
				
			||||||
 | 
					                    );
 | 
				
			||||||
 | 
					                **********************************************/    
 | 
				
			||||||
 | 
					                      NIMBLE_PROPERTY::READ   |
 | 
				
			||||||
 | 
					                      NIMBLE_PROPERTY::WRITE  |
 | 
				
			||||||
 | 
					                      NIMBLE_PROPERTY::NOTIFY |
 | 
				
			||||||
 | 
					                      NIMBLE_PROPERTY::INDICATE
 | 
				
			||||||
 | 
					                    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml
 | 
				
			||||||
 | 
					  // Create a BLE Descriptor
 | 
				
			||||||
 | 
					  /***************************************************   
 | 
				
			||||||
 | 
					   NOTE: DO NOT create a 2902 descriptor. 
 | 
				
			||||||
 | 
					   it will be created automatically if notifications 
 | 
				
			||||||
 | 
					   or indications are enabled on a characteristic.
 | 
				
			||||||
 | 
					   
 | 
				
			||||||
 | 
					   pCharacteristic->addDescriptor(new BLE2902());
 | 
				
			||||||
 | 
					  ****************************************************/
 | 
				
			||||||
 | 
					  // Start the service
 | 
				
			||||||
 | 
					  pService->start();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Start advertising
 | 
				
			||||||
 | 
					  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
 | 
				
			||||||
 | 
					  pAdvertising->addServiceUUID(SERVICE_UUID);
 | 
				
			||||||
 | 
					  pAdvertising->setScanResponse(false);
 | 
				
			||||||
 | 
					  /** This method had been removed **
 | 
				
			||||||
 | 
					  pAdvertising->setMinPreferred(0x0);  // set value to 0x00 to not advertise this parameter
 | 
				
			||||||
 | 
					  **/
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  xTaskCreate(connectedTask, "connectedTask", 5000, NULL, 1, NULL);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  BLEDevice::startAdvertising();
 | 
				
			||||||
 | 
					  printf("Waiting a client connection to notify...\n");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					# The following lines of boilerplate have to be in your project's
 | 
				
			||||||
 | 
					# CMakeLists in this exact order for cmake to work correctly
 | 
				
			||||||
 | 
					cmake_minimum_required(VERSION 3.5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include($ENV{IDF_PATH}/tools/cmake/project.cmake)
 | 
				
			||||||
 | 
					set(SUPPORTED_TARGETS esp32)
 | 
				
			||||||
 | 
					project(BLE_scan)
 | 
				
			||||||
@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					PROJECT_NAME := BLE_scan
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include $(IDF_PATH)/make/project.mk
 | 
				
			||||||
@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					set(COMPONENT_SRCS "main.cpp")
 | 
				
			||||||
 | 
					set(COMPONENT_ADD_INCLUDEDIRS ".")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					register_component()
 | 
				
			||||||
@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					#
 | 
				
			||||||
 | 
					# "main" pseudo-component makefile.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
 | 
				
			||||||
@@ -0,0 +1,52 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					   Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleScan.cpp
 | 
				
			||||||
 | 
					   Ported to Arduino ESP32 by Evandro Copercini
 | 
				
			||||||
 | 
					   Refactored back to IDF by H2zero
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** NimBLE differences highlighted in comment blocks **/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******original********
 | 
				
			||||||
 | 
					#include <BLEDevice.h>
 | 
				
			||||||
 | 
					#include <BLEUtils.h>
 | 
				
			||||||
 | 
					#include <BLEScan.h>
 | 
				
			||||||
 | 
					#include <BLEAdvertisedDevice.h>
 | 
				
			||||||
 | 
					***********************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <NimBLEDevice.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern "C"{void app_main(void);}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int scanTime = 5; //In seconds
 | 
				
			||||||
 | 
					BLEScan* pBLEScan;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
 | 
				
			||||||
 | 
					    void onResult(BLEAdvertisedDevice* advertisedDevice) {
 | 
				
			||||||
 | 
					      printf("Advertised Device: %s \n", advertisedDevice->toString().c_str());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void scanTask (void * parameter){
 | 
				
			||||||
 | 
					    for(;;) {
 | 
				
			||||||
 | 
					        // put your main code here, to run repeatedly:
 | 
				
			||||||
 | 
					        BLEScanResults foundDevices = pBLEScan->start(scanTime, false);
 | 
				
			||||||
 | 
					        printf("Devices found: %d\n", foundDevices.getCount());
 | 
				
			||||||
 | 
					        printf("Scan done!\n");
 | 
				
			||||||
 | 
					        pBLEScan->clearResults();   // delete results fromBLEScan buffer to release memory
 | 
				
			||||||
 | 
					        vTaskDelay(2000/portTICK_PERIOD_MS); // Delay a second between loops.
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    vTaskDelete(NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void app_main(void) {
 | 
				
			||||||
 | 
					  printf("Scanning...\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  BLEDevice::init("");
 | 
				
			||||||
 | 
					  pBLEScan = BLEDevice::getScan(); //create new scan
 | 
				
			||||||
 | 
					  pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
 | 
				
			||||||
 | 
					  pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster
 | 
				
			||||||
 | 
					  pBLEScan->setInterval(100);
 | 
				
			||||||
 | 
					  pBLEScan->setWindow(99);  // less or equal setInterval value
 | 
				
			||||||
 | 
					  xTaskCreate(scanTask, "scanTask", 5000, NULL, 1, NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					# The following lines of boilerplate have to be in your project's
 | 
				
			||||||
 | 
					# CMakeLists in this exact order for cmake to work correctly
 | 
				
			||||||
 | 
					cmake_minimum_required(VERSION 3.5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include($ENV{IDF_PATH}/tools/cmake/project.cmake)
 | 
				
			||||||
 | 
					set(SUPPORTED_TARGETS esp32)
 | 
				
			||||||
 | 
					project(BLE_server)
 | 
				
			||||||
@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					PROJECT_NAME := BLE_server
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include $(IDF_PATH)/make/project.mk
 | 
				
			||||||
@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					set(COMPONENT_SRCS "main.cpp")
 | 
				
			||||||
 | 
					set(COMPONENT_ADD_INCLUDEDIRS ".")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					register_component()
 | 
				
			||||||
@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					#
 | 
				
			||||||
 | 
					# "main" pseudo-component makefile.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
 | 
				
			||||||
@@ -0,0 +1,57 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					    Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleServer.cpp
 | 
				
			||||||
 | 
					    Ported to Arduino ESP32 by Evandro Copercini
 | 
				
			||||||
 | 
					    updates by chegewara
 | 
				
			||||||
 | 
					    Refactored back to IDF by H2zero
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** NimBLE differences highlighted in comment blocks **/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******original********
 | 
				
			||||||
 | 
					#include <BLEDevice.h>
 | 
				
			||||||
 | 
					#include <BLEUtils.h>
 | 
				
			||||||
 | 
					#include <BLEServer.h>
 | 
				
			||||||
 | 
					***********************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <NimBLEDevice.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern "C"{void app_main(void);}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// See the following for generating UUIDs:
 | 
				
			||||||
 | 
					// https://www.uuidgenerator.net/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SERVICE_UUID        "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
 | 
				
			||||||
 | 
					#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void app_main(void) {
 | 
				
			||||||
 | 
					  printf("Starting BLE work!\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  BLEDevice::init("Long name works now");
 | 
				
			||||||
 | 
					  BLEServer *pServer = BLEDevice::createServer();
 | 
				
			||||||
 | 
					  BLEService *pService = pServer->createService(SERVICE_UUID);
 | 
				
			||||||
 | 
					  BLECharacteristic *pCharacteristic = pService->createCharacteristic(
 | 
				
			||||||
 | 
					                                        CHARACTERISTIC_UUID,
 | 
				
			||||||
 | 
					                                  /***** Enum Type NIMBLE_PROPERTY now *****      
 | 
				
			||||||
 | 
					                                        BLECharacteristic::PROPERTY_READ   |
 | 
				
			||||||
 | 
					                                        BLECharacteristic::PROPERTY_WRITE  
 | 
				
			||||||
 | 
					                                        );
 | 
				
			||||||
 | 
					                                  *****************************************/
 | 
				
			||||||
 | 
					                                        NIMBLE_PROPERTY::READ |
 | 
				
			||||||
 | 
					                                        NIMBLE_PROPERTY::WRITE 
 | 
				
			||||||
 | 
					                                       );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pCharacteristic->setValue("Hello World says Neil");
 | 
				
			||||||
 | 
					  pService->start();
 | 
				
			||||||
 | 
					  // BLEAdvertising *pAdvertising = pServer->getAdvertising();  // this still is working for backward compatibility
 | 
				
			||||||
 | 
					  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
 | 
				
			||||||
 | 
					  pAdvertising->addServiceUUID(SERVICE_UUID);
 | 
				
			||||||
 | 
					  pAdvertising->setScanResponse(true);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  /** These methods have been removed **
 | 
				
			||||||
 | 
					  pAdvertising->setMinPreferred(0x06);  // functions that help with iPhone connections issue
 | 
				
			||||||
 | 
					  pAdvertising->setMinPreferred(0x12);
 | 
				
			||||||
 | 
					  */
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  BLEDevice::startAdvertising();
 | 
				
			||||||
 | 
					  printf("Characteristic defined! Now you can read it in your phone!\n");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					# The following lines of boilerplate have to be in your project's
 | 
				
			||||||
 | 
					# CMakeLists in this exact order for cmake to work correctly
 | 
				
			||||||
 | 
					cmake_minimum_required(VERSION 3.5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include($ENV{IDF_PATH}/tools/cmake/project.cmake)
 | 
				
			||||||
 | 
					set(SUPPORTED_TARGETS esp32)
 | 
				
			||||||
 | 
					project(BLE_uart)
 | 
				
			||||||
@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					PROJECT_NAME := BLE_uart
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include $(IDF_PATH)/make/project.mk
 | 
				
			||||||
@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					set(COMPONENT_SRCS "main.cpp")
 | 
				
			||||||
 | 
					set(COMPONENT_ADD_INCLUDEDIRS ".")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					register_component()
 | 
				
			||||||
@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					#
 | 
				
			||||||
 | 
					# "main" pseudo-component makefile.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
 | 
				
			||||||
@@ -0,0 +1,167 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					    Video: https://www.youtube.com/watch?v=oCMOYS71NIU
 | 
				
			||||||
 | 
					    Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleNotify.cpp
 | 
				
			||||||
 | 
					    Ported to Arduino ESP32 by Evandro Copercini
 | 
				
			||||||
 | 
					    Refactored back to IDF by H2zero
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   Create a BLE server that, once we receive a connection, will send periodic notifications.
 | 
				
			||||||
 | 
					   The service advertises itself as: 6E400001-B5A3-F393-E0A9-E50E24DCCA9E
 | 
				
			||||||
 | 
					   Has a characteristic of: 6E400002-B5A3-F393-E0A9-E50E24DCCA9E - used for receiving data with "WRITE" 
 | 
				
			||||||
 | 
					   Has a characteristic of: 6E400003-B5A3-F393-E0A9-E50E24DCCA9E - used to send data with  "NOTIFY"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   The design of creating the BLE server is:
 | 
				
			||||||
 | 
					   1. Create a BLE Server
 | 
				
			||||||
 | 
					   2. Create a BLE Service
 | 
				
			||||||
 | 
					   3. Create a BLE Characteristic on the Service
 | 
				
			||||||
 | 
					   4. Create a BLE Descriptor on the characteristic
 | 
				
			||||||
 | 
					   5. Start the service.
 | 
				
			||||||
 | 
					   6. Start advertising.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   In this example rxValue is the data received (only accessible inside that function).
 | 
				
			||||||
 | 
					   And txValue is the data to be sent, in this example just a byte incremented every second. 
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** NimBLE differences highlighted in comment blocks **/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*******original********
 | 
				
			||||||
 | 
					#include <BLEDevice.h>
 | 
				
			||||||
 | 
					#include <BLEServer.h>
 | 
				
			||||||
 | 
					#include <BLEUtils.h>
 | 
				
			||||||
 | 
					#include <BLE2902.h>
 | 
				
			||||||
 | 
					***********************/
 | 
				
			||||||
 | 
					#include <NimBLEDevice.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern "C"{void app_main(void);}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BLEServer *pServer = NULL;
 | 
				
			||||||
 | 
					BLECharacteristic * pTxCharacteristic;
 | 
				
			||||||
 | 
					bool deviceConnected = false;
 | 
				
			||||||
 | 
					bool oldDeviceConnected = false;
 | 
				
			||||||
 | 
					uint8_t txValue = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// See the following for generating UUIDs:
 | 
				
			||||||
 | 
					// https://www.uuidgenerator.net/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SERVICE_UUID           "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUID
 | 
				
			||||||
 | 
					#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
 | 
				
			||||||
 | 
					#define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**  None of these are required as they will be handled by the library with defaults. **
 | 
				
			||||||
 | 
					 **                       Remove as you see fit for your needs                        */  
 | 
				
			||||||
 | 
					class MyServerCallbacks: public BLEServerCallbacks {
 | 
				
			||||||
 | 
					    void onConnect(BLEServer* pServer) {
 | 
				
			||||||
 | 
					      deviceConnected = true;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void onDisconnect(BLEServer* pServer) {
 | 
				
			||||||
 | 
					      deviceConnected = false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  /***************** New - Security handled here ********************
 | 
				
			||||||
 | 
					  ****** Note: these are the same return values as defaults ********/
 | 
				
			||||||
 | 
					    uint32_t onPassKeyRequest(){
 | 
				
			||||||
 | 
					      printf("Server PassKeyRequest\n");
 | 
				
			||||||
 | 
					      return 123456; 
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool onConfirmPIN(uint32_t pass_key){
 | 
				
			||||||
 | 
					      printf("The passkey YES/NO number: %d\n", pass_key);
 | 
				
			||||||
 | 
					      return true; 
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void onAuthenticationComplete(ble_gap_conn_desc desc){
 | 
				
			||||||
 | 
					      printf("Starting BLE work!\n");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  /*******************************************************************/
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MyCallbacks: public BLECharacteristicCallbacks {
 | 
				
			||||||
 | 
					    void onWrite(BLECharacteristic *pCharacteristic) {
 | 
				
			||||||
 | 
					      std::string rxValue = pCharacteristic->getValue();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (rxValue.length() > 0) {
 | 
				
			||||||
 | 
					        printf("*********\n");
 | 
				
			||||||
 | 
					        printf("Received Value: ");
 | 
				
			||||||
 | 
					        for (int i = 0; i < rxValue.length(); i++)
 | 
				
			||||||
 | 
					          printf("%d", rxValue[i]);
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					        printf("\n*********\n");
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void connectedTask (void * parameter){
 | 
				
			||||||
 | 
					    for(;;) {
 | 
				
			||||||
 | 
					        if (deviceConnected) {
 | 
				
			||||||
 | 
					            pTxCharacteristic->setValue(&txValue, 1);
 | 
				
			||||||
 | 
					            pTxCharacteristic->notify();
 | 
				
			||||||
 | 
					            txValue++;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // disconnecting
 | 
				
			||||||
 | 
					        if (!deviceConnected && oldDeviceConnected) {
 | 
				
			||||||
 | 
					            pServer->startAdvertising(); // restart advertising
 | 
				
			||||||
 | 
					            printf("start advertising\n");
 | 
				
			||||||
 | 
					            oldDeviceConnected = deviceConnected;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // connecting
 | 
				
			||||||
 | 
					        if (deviceConnected && !oldDeviceConnected) {
 | 
				
			||||||
 | 
					            // do stuff here on connecting
 | 
				
			||||||
 | 
					            oldDeviceConnected = deviceConnected;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        vTaskDelay(10/portTICK_PERIOD_MS); // Delay between loops to reset watchdog timer
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    vTaskDelete(NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void app_main(void) {
 | 
				
			||||||
 | 
					  // Create the BLE Device
 | 
				
			||||||
 | 
					  BLEDevice::init("UART Service");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Create the BLE Server
 | 
				
			||||||
 | 
					  pServer = BLEDevice::createServer();
 | 
				
			||||||
 | 
					  pServer->setCallbacks(new MyServerCallbacks());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Create the BLE Service
 | 
				
			||||||
 | 
					  BLEService *pService = pServer->createService(SERVICE_UUID);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Create a BLE Characteristic
 | 
				
			||||||
 | 
					  pTxCharacteristic = pService->createCharacteristic(
 | 
				
			||||||
 | 
					                                        CHARACTERISTIC_UUID_TX,
 | 
				
			||||||
 | 
					                                    /******* Enum Type NIMBLE_PROPERTY now *******      
 | 
				
			||||||
 | 
					                                        BLECharacteristic::PROPERTY_NOTIFY
 | 
				
			||||||
 | 
					                                        );
 | 
				
			||||||
 | 
					                                    **********************************************/  
 | 
				
			||||||
 | 
					                                        NIMBLE_PROPERTY::NOTIFY
 | 
				
			||||||
 | 
					                                       );
 | 
				
			||||||
 | 
					                                    
 | 
				
			||||||
 | 
					  /***************************************************   
 | 
				
			||||||
 | 
					   NOTE: DO NOT create a 2902 descriptor 
 | 
				
			||||||
 | 
					   it will be created automatically if notifications 
 | 
				
			||||||
 | 
					   or indications are enabled on a characteristic.
 | 
				
			||||||
 | 
					   
 | 
				
			||||||
 | 
					   pCharacteristic->addDescriptor(new BLE2902());
 | 
				
			||||||
 | 
					  ****************************************************/                  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  BLECharacteristic * pRxCharacteristic = pService->createCharacteristic(
 | 
				
			||||||
 | 
					                                            CHARACTERISTIC_UUID_RX,
 | 
				
			||||||
 | 
					                                    /******* Enum Type NIMBLE_PROPERTY now *******       
 | 
				
			||||||
 | 
					                                            BLECharacteristic::PROPERTY_WRITE
 | 
				
			||||||
 | 
					                                            );
 | 
				
			||||||
 | 
					                                    *********************************************/  
 | 
				
			||||||
 | 
					                                            NIMBLE_PROPERTY::WRITE
 | 
				
			||||||
 | 
					                                            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pRxCharacteristic->setCallbacks(new MyCallbacks());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Start the service
 | 
				
			||||||
 | 
					  pService->start();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  xTaskCreate(connectedTask, "connectedTask", 5000, NULL, 1, NULL);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // Start advertising
 | 
				
			||||||
 | 
					  pServer->getAdvertising()->start();
 | 
				
			||||||
 | 
					  printf("Waiting a client connection to notify...\n");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										402
									
								
								src/components/esp-nimble-cpp-1.3.3/src/HIDKeyboardTypes.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										402
									
								
								src/components/esp-nimble-cpp-1.3.3/src/HIDKeyboardTypes.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,402 @@
 | 
				
			|||||||
 | 
					/* Copyright (c) 2015 mbed.org, MIT License
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Note: this file was pulled from different parts of the USBHID library, in mbed SDK
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef KEYBOARD_DEFS_H
 | 
				
			||||||
 | 
					#define KEYBOARD_DEFS_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define REPORT_ID_KEYBOARD 1
 | 
				
			||||||
 | 
					#define REPORT_ID_VOLUME   3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Modifiers */
 | 
				
			||||||
 | 
					enum MODIFIER_KEY {
 | 
				
			||||||
 | 
					    KEY_CTRL = 1,
 | 
				
			||||||
 | 
					    KEY_SHIFT = 2,
 | 
				
			||||||
 | 
					    KEY_ALT = 4,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum MEDIA_KEY {
 | 
				
			||||||
 | 
					    KEY_NEXT_TRACK,     /*!< next Track Button */
 | 
				
			||||||
 | 
					    KEY_PREVIOUS_TRACK, /*!< Previous track Button */
 | 
				
			||||||
 | 
					    KEY_STOP,           /*!< Stop Button */
 | 
				
			||||||
 | 
					    KEY_PLAY_PAUSE,     /*!< Play/Pause Button */
 | 
				
			||||||
 | 
					    KEY_MUTE,           /*!< Mute Button */
 | 
				
			||||||
 | 
					    KEY_VOLUME_UP,      /*!< Volume Up Button */
 | 
				
			||||||
 | 
					    KEY_VOLUME_DOWN,    /*!< Volume Down Button */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum FUNCTION_KEY {
 | 
				
			||||||
 | 
					    KEY_F1 = 128,   /* F1 key */
 | 
				
			||||||
 | 
					    KEY_F2,      /* F2 key */
 | 
				
			||||||
 | 
					    KEY_F3,      /* F3 key */
 | 
				
			||||||
 | 
					    KEY_F4,      /* F4 key */
 | 
				
			||||||
 | 
					    KEY_F5,      /* F5 key */
 | 
				
			||||||
 | 
					    KEY_F6,      /* F6 key */
 | 
				
			||||||
 | 
					    KEY_F7,      /* F7 key */
 | 
				
			||||||
 | 
					    KEY_F8,      /* F8 key */
 | 
				
			||||||
 | 
					    KEY_F9,      /* F9 key */
 | 
				
			||||||
 | 
					    KEY_F10,        /* F10 key */
 | 
				
			||||||
 | 
					    KEY_F11,        /* F11 key */
 | 
				
			||||||
 | 
					    KEY_F12,        /* F12 key */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    KEY_PRINT_SCREEN,   /* Print Screen key */
 | 
				
			||||||
 | 
					    KEY_SCROLL_LOCK,    /* Scroll lock */
 | 
				
			||||||
 | 
					    KEY_CAPS_LOCK,    /* caps lock */
 | 
				
			||||||
 | 
					    KEY_NUM_LOCK,      /* num lock */
 | 
				
			||||||
 | 
					    KEY_INSERT,      /* Insert key */
 | 
				
			||||||
 | 
					    KEY_HOME,          /* Home key */
 | 
				
			||||||
 | 
					    KEY_PAGE_UP,        /* Page Up key */
 | 
				
			||||||
 | 
					    KEY_PAGE_DOWN,    /* Page Down key */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    RIGHT_ARROW,        /* Right arrow */
 | 
				
			||||||
 | 
					    LEFT_ARROW,      /* Left arrow */
 | 
				
			||||||
 | 
					    DOWN_ARROW,      /* Down arrow */
 | 
				
			||||||
 | 
					    UP_ARROW,          /* Up arrow */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					    unsigned char usage;
 | 
				
			||||||
 | 
					    unsigned char modifier;
 | 
				
			||||||
 | 
					} KEYMAP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef US_KEYBOARD
 | 
				
			||||||
 | 
					/* US keyboard (as HID standard) */
 | 
				
			||||||
 | 
					#define KEYMAP_SIZE (152)
 | 
				
			||||||
 | 
					const KEYMAP keymap[KEYMAP_SIZE] = {
 | 
				
			||||||
 | 
					    {0, 0},             /* NUL */
 | 
				
			||||||
 | 
					    {0, 0},             /* SOH */
 | 
				
			||||||
 | 
					    {0, 0},             /* STX */
 | 
				
			||||||
 | 
					    {0, 0},             /* ETX */
 | 
				
			||||||
 | 
					    {0, 0},             /* EOT */
 | 
				
			||||||
 | 
					    {0, 0},             /* ENQ */
 | 
				
			||||||
 | 
					    {0, 0},             /* ACK */
 | 
				
			||||||
 | 
					    {0, 0},             /* BEL */
 | 
				
			||||||
 | 
					    {0x2a, 0},          /* BS  */  /* Keyboard Delete (Backspace) */
 | 
				
			||||||
 | 
					    {0x2b, 0},          /* TAB */  /* Keyboard Tab */
 | 
				
			||||||
 | 
					    {0x28, 0},          /* LF  */  /* Keyboard Return (Enter) */
 | 
				
			||||||
 | 
					    {0, 0},             /* VT  */
 | 
				
			||||||
 | 
					    {0, 0},             /* FF  */
 | 
				
			||||||
 | 
					    {0, 0},             /* CR  */
 | 
				
			||||||
 | 
					    {0, 0},             /* SO  */
 | 
				
			||||||
 | 
					    {0, 0},             /* SI  */
 | 
				
			||||||
 | 
					    {0, 0},             /* DEL */
 | 
				
			||||||
 | 
					    {0, 0},             /* DC1 */
 | 
				
			||||||
 | 
					    {0, 0},             /* DC2 */
 | 
				
			||||||
 | 
					    {0, 0},             /* DC3 */
 | 
				
			||||||
 | 
					    {0, 0},             /* DC4 */
 | 
				
			||||||
 | 
					    {0, 0},             /* NAK */
 | 
				
			||||||
 | 
					    {0, 0},             /* SYN */
 | 
				
			||||||
 | 
					    {0, 0},             /* ETB */
 | 
				
			||||||
 | 
					    {0, 0},             /* CAN */
 | 
				
			||||||
 | 
					    {0, 0},             /* EM  */
 | 
				
			||||||
 | 
					    {0, 0},             /* SUB */
 | 
				
			||||||
 | 
					    {0, 0},             /* ESC */
 | 
				
			||||||
 | 
					    {0, 0},             /* FS  */
 | 
				
			||||||
 | 
					    {0, 0},             /* GS  */
 | 
				
			||||||
 | 
					    {0, 0},             /* RS  */
 | 
				
			||||||
 | 
					    {0, 0},             /* US  */
 | 
				
			||||||
 | 
					    {0x2c, 0},          /*   */
 | 
				
			||||||
 | 
					    {0x1e, KEY_SHIFT},      /* ! */
 | 
				
			||||||
 | 
					    {0x34, KEY_SHIFT},      /* " */
 | 
				
			||||||
 | 
					    {0x20, KEY_SHIFT},      /* # */
 | 
				
			||||||
 | 
					    {0x21, KEY_SHIFT},      /* $ */
 | 
				
			||||||
 | 
					    {0x22, KEY_SHIFT},      /* % */
 | 
				
			||||||
 | 
					    {0x24, KEY_SHIFT},      /* & */
 | 
				
			||||||
 | 
					    {0x34, 0},          /* ' */
 | 
				
			||||||
 | 
					    {0x26, KEY_SHIFT},      /* ( */
 | 
				
			||||||
 | 
					    {0x27, KEY_SHIFT},      /* ) */
 | 
				
			||||||
 | 
					    {0x25, KEY_SHIFT},      /* * */
 | 
				
			||||||
 | 
					    {0x2e, KEY_SHIFT},      /* + */
 | 
				
			||||||
 | 
					    {0x36, 0},          /* , */
 | 
				
			||||||
 | 
					    {0x2d, 0},          /* - */
 | 
				
			||||||
 | 
					    {0x37, 0},          /* . */
 | 
				
			||||||
 | 
					    {0x38, 0},          /* / */
 | 
				
			||||||
 | 
					    {0x27, 0},          /* 0 */
 | 
				
			||||||
 | 
					    {0x1e, 0},          /* 1 */
 | 
				
			||||||
 | 
					    {0x1f, 0},          /* 2 */
 | 
				
			||||||
 | 
					    {0x20, 0},          /* 3 */
 | 
				
			||||||
 | 
					    {0x21, 0},          /* 4 */
 | 
				
			||||||
 | 
					    {0x22, 0},          /* 5 */
 | 
				
			||||||
 | 
					    {0x23, 0},          /* 6 */
 | 
				
			||||||
 | 
					    {0x24, 0},          /* 7 */
 | 
				
			||||||
 | 
					    {0x25, 0},          /* 8 */
 | 
				
			||||||
 | 
					    {0x26, 0},          /* 9 */
 | 
				
			||||||
 | 
					    {0x33, KEY_SHIFT},      /* : */
 | 
				
			||||||
 | 
					    {0x33, 0},          /* ; */
 | 
				
			||||||
 | 
					    {0x36, KEY_SHIFT},      /* < */
 | 
				
			||||||
 | 
					    {0x2e, 0},          /* = */
 | 
				
			||||||
 | 
					    {0x37, KEY_SHIFT},      /* > */
 | 
				
			||||||
 | 
					    {0x38, KEY_SHIFT},      /* ? */
 | 
				
			||||||
 | 
					    {0x1f, KEY_SHIFT},      /* @ */
 | 
				
			||||||
 | 
					    {0x04, KEY_SHIFT},      /* A */
 | 
				
			||||||
 | 
					    {0x05, KEY_SHIFT},      /* B */
 | 
				
			||||||
 | 
					    {0x06, KEY_SHIFT},      /* C */
 | 
				
			||||||
 | 
					    {0x07, KEY_SHIFT},      /* D */
 | 
				
			||||||
 | 
					    {0x08, KEY_SHIFT},      /* E */
 | 
				
			||||||
 | 
					    {0x09, KEY_SHIFT},      /* F */
 | 
				
			||||||
 | 
					    {0x0a, KEY_SHIFT},      /* G */
 | 
				
			||||||
 | 
					    {0x0b, KEY_SHIFT},      /* H */
 | 
				
			||||||
 | 
					    {0x0c, KEY_SHIFT},      /* I */
 | 
				
			||||||
 | 
					    {0x0d, KEY_SHIFT},      /* J */
 | 
				
			||||||
 | 
					    {0x0e, KEY_SHIFT},      /* K */
 | 
				
			||||||
 | 
					    {0x0f, KEY_SHIFT},      /* L */
 | 
				
			||||||
 | 
					    {0x10, KEY_SHIFT},      /* M */
 | 
				
			||||||
 | 
					    {0x11, KEY_SHIFT},      /* N */
 | 
				
			||||||
 | 
					    {0x12, KEY_SHIFT},      /* O */
 | 
				
			||||||
 | 
					    {0x13, KEY_SHIFT},      /* P */
 | 
				
			||||||
 | 
					    {0x14, KEY_SHIFT},      /* Q */
 | 
				
			||||||
 | 
					    {0x15, KEY_SHIFT},      /* R */
 | 
				
			||||||
 | 
					    {0x16, KEY_SHIFT},      /* S */
 | 
				
			||||||
 | 
					    {0x17, KEY_SHIFT},      /* T */
 | 
				
			||||||
 | 
					    {0x18, KEY_SHIFT},      /* U */
 | 
				
			||||||
 | 
					    {0x19, KEY_SHIFT},      /* V */
 | 
				
			||||||
 | 
					    {0x1a, KEY_SHIFT},      /* W */
 | 
				
			||||||
 | 
					    {0x1b, KEY_SHIFT},      /* X */
 | 
				
			||||||
 | 
					    {0x1c, KEY_SHIFT},      /* Y */
 | 
				
			||||||
 | 
					    {0x1d, KEY_SHIFT},      /* Z */
 | 
				
			||||||
 | 
					    {0x2f, 0},          /* [ */
 | 
				
			||||||
 | 
					    {0x31, 0},          /* \ */
 | 
				
			||||||
 | 
					    {0x30, 0},          /* ] */
 | 
				
			||||||
 | 
					    {0x23, KEY_SHIFT},      /* ^ */
 | 
				
			||||||
 | 
					    {0x2d, KEY_SHIFT},      /* _ */
 | 
				
			||||||
 | 
					    {0x35, 0},          /* ` */
 | 
				
			||||||
 | 
					    {0x04, 0},          /* a */
 | 
				
			||||||
 | 
					    {0x05, 0},          /* b */
 | 
				
			||||||
 | 
					    {0x06, 0},          /* c */
 | 
				
			||||||
 | 
					    {0x07, 0},          /* d */
 | 
				
			||||||
 | 
					    {0x08, 0},          /* e */
 | 
				
			||||||
 | 
					    {0x09, 0},          /* f */
 | 
				
			||||||
 | 
					    {0x0a, 0},          /* g */
 | 
				
			||||||
 | 
					    {0x0b, 0},          /* h */
 | 
				
			||||||
 | 
					    {0x0c, 0},          /* i */
 | 
				
			||||||
 | 
					    {0x0d, 0},          /* j */
 | 
				
			||||||
 | 
					    {0x0e, 0},          /* k */
 | 
				
			||||||
 | 
					    {0x0f, 0},          /* l */
 | 
				
			||||||
 | 
					    {0x10, 0},          /* m */
 | 
				
			||||||
 | 
					    {0x11, 0},          /* n */
 | 
				
			||||||
 | 
					    {0x12, 0},          /* o */
 | 
				
			||||||
 | 
					    {0x13, 0},          /* p */
 | 
				
			||||||
 | 
					    {0x14, 0},          /* q */
 | 
				
			||||||
 | 
					    {0x15, 0},          /* r */
 | 
				
			||||||
 | 
					    {0x16, 0},          /* s */
 | 
				
			||||||
 | 
					    {0x17, 0},          /* t */
 | 
				
			||||||
 | 
					    {0x18, 0},          /* u */
 | 
				
			||||||
 | 
					    {0x19, 0},          /* v */
 | 
				
			||||||
 | 
					    {0x1a, 0},          /* w */
 | 
				
			||||||
 | 
					    {0x1b, 0},          /* x */
 | 
				
			||||||
 | 
					    {0x1c, 0},          /* y */
 | 
				
			||||||
 | 
					    {0x1d, 0},          /* z */
 | 
				
			||||||
 | 
					    {0x2f, KEY_SHIFT},      /* { */
 | 
				
			||||||
 | 
					    {0x31, KEY_SHIFT},      /* | */
 | 
				
			||||||
 | 
					    {0x30, KEY_SHIFT},      /* } */
 | 
				
			||||||
 | 
					    {0x35, KEY_SHIFT},      /* ~ */
 | 
				
			||||||
 | 
					    {0,0},              /* DEL */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    {0x3a, 0},          /* F1 */
 | 
				
			||||||
 | 
					    {0x3b, 0},          /* F2 */
 | 
				
			||||||
 | 
					    {0x3c, 0},          /* F3 */
 | 
				
			||||||
 | 
					    {0x3d, 0},          /* F4 */
 | 
				
			||||||
 | 
					    {0x3e, 0},          /* F5 */
 | 
				
			||||||
 | 
					    {0x3f, 0},          /* F6 */
 | 
				
			||||||
 | 
					    {0x40, 0},          /* F7 */
 | 
				
			||||||
 | 
					    {0x41, 0},          /* F8 */
 | 
				
			||||||
 | 
					    {0x42, 0},          /* F9 */
 | 
				
			||||||
 | 
					    {0x43, 0},          /* F10 */
 | 
				
			||||||
 | 
					    {0x44, 0},          /* F11 */
 | 
				
			||||||
 | 
					    {0x45, 0},          /* F12 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    {0x46, 0},          /* PRINT_SCREEN */
 | 
				
			||||||
 | 
					    {0x47, 0},          /* SCROLL_LOCK */
 | 
				
			||||||
 | 
					    {0x39, 0},          /* CAPS_LOCK */
 | 
				
			||||||
 | 
					    {0x53, 0},          /* NUM_LOCK */
 | 
				
			||||||
 | 
					    {0x49, 0},          /* INSERT */
 | 
				
			||||||
 | 
					    {0x4a, 0},          /* HOME */
 | 
				
			||||||
 | 
					    {0x4b, 0},          /* PAGE_UP */
 | 
				
			||||||
 | 
					    {0x4e, 0},          /* PAGE_DOWN */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    {0x4f, 0},          /* RIGHT_ARROW */
 | 
				
			||||||
 | 
					    {0x50, 0},          /* LEFT_ARROW */
 | 
				
			||||||
 | 
					    {0x51, 0},          /* DOWN_ARROW */
 | 
				
			||||||
 | 
					    {0x52, 0},          /* UP_ARROW */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					/* UK keyboard */
 | 
				
			||||||
 | 
					#define KEYMAP_SIZE (152)
 | 
				
			||||||
 | 
					const KEYMAP keymap[KEYMAP_SIZE] = {
 | 
				
			||||||
 | 
					    {0, 0},             /* NUL */
 | 
				
			||||||
 | 
					    {0, 0},             /* SOH */
 | 
				
			||||||
 | 
					    {0, 0},             /* STX */
 | 
				
			||||||
 | 
					    {0, 0},             /* ETX */
 | 
				
			||||||
 | 
					    {0, 0},             /* EOT */
 | 
				
			||||||
 | 
					    {0, 0},             /* ENQ */
 | 
				
			||||||
 | 
					    {0, 0},             /* ACK */
 | 
				
			||||||
 | 
					    {0, 0},             /* BEL */
 | 
				
			||||||
 | 
					    {0x2a, 0},          /* BS  */  /* Keyboard Delete (Backspace) */
 | 
				
			||||||
 | 
					    {0x2b, 0},          /* TAB */  /* Keyboard Tab */
 | 
				
			||||||
 | 
					    {0x28, 0},          /* LF  */  /* Keyboard Return (Enter) */
 | 
				
			||||||
 | 
					    {0, 0},             /* VT  */
 | 
				
			||||||
 | 
					    {0, 0},             /* FF  */
 | 
				
			||||||
 | 
					    {0, 0},             /* CR  */
 | 
				
			||||||
 | 
					    {0, 0},             /* SO  */
 | 
				
			||||||
 | 
					    {0, 0},             /* SI  */
 | 
				
			||||||
 | 
					    {0, 0},             /* DEL */
 | 
				
			||||||
 | 
					    {0, 0},             /* DC1 */
 | 
				
			||||||
 | 
					    {0, 0},             /* DC2 */
 | 
				
			||||||
 | 
					    {0, 0},             /* DC3 */
 | 
				
			||||||
 | 
					    {0, 0},             /* DC4 */
 | 
				
			||||||
 | 
					    {0, 0},             /* NAK */
 | 
				
			||||||
 | 
					    {0, 0},             /* SYN */
 | 
				
			||||||
 | 
					    {0, 0},             /* ETB */
 | 
				
			||||||
 | 
					    {0, 0},             /* CAN */
 | 
				
			||||||
 | 
					    {0, 0},             /* EM  */
 | 
				
			||||||
 | 
					    {0, 0},             /* SUB */
 | 
				
			||||||
 | 
					    {0, 0},             /* ESC */
 | 
				
			||||||
 | 
					    {0, 0},             /* FS  */
 | 
				
			||||||
 | 
					    {0, 0},             /* GS  */
 | 
				
			||||||
 | 
					    {0, 0},             /* RS  */
 | 
				
			||||||
 | 
					    {0, 0},             /* US  */
 | 
				
			||||||
 | 
					    {0x2c, 0},          /*   */
 | 
				
			||||||
 | 
					    {0x1e, KEY_SHIFT},      /* ! */
 | 
				
			||||||
 | 
					    {0x1f, KEY_SHIFT},      /* " */
 | 
				
			||||||
 | 
					    {0x32, 0},          /* # */
 | 
				
			||||||
 | 
					    {0x21, KEY_SHIFT},      /* $ */
 | 
				
			||||||
 | 
					    {0x22, KEY_SHIFT},      /* % */
 | 
				
			||||||
 | 
					    {0x24, KEY_SHIFT},      /* & */
 | 
				
			||||||
 | 
					    {0x34, 0},          /* ' */
 | 
				
			||||||
 | 
					    {0x26, KEY_SHIFT},      /* ( */
 | 
				
			||||||
 | 
					    {0x27, KEY_SHIFT},      /* ) */
 | 
				
			||||||
 | 
					    {0x25, KEY_SHIFT},      /* * */
 | 
				
			||||||
 | 
					    {0x2e, KEY_SHIFT},      /* + */
 | 
				
			||||||
 | 
					    {0x36, 0},          /* , */
 | 
				
			||||||
 | 
					    {0x2d, 0},          /* - */
 | 
				
			||||||
 | 
					    {0x37, 0},          /* . */
 | 
				
			||||||
 | 
					    {0x38, 0},          /* / */
 | 
				
			||||||
 | 
					    {0x27, 0},          /* 0 */
 | 
				
			||||||
 | 
					    {0x1e, 0},          /* 1 */
 | 
				
			||||||
 | 
					    {0x1f, 0},          /* 2 */
 | 
				
			||||||
 | 
					    {0x20, 0},          /* 3 */
 | 
				
			||||||
 | 
					    {0x21, 0},          /* 4 */
 | 
				
			||||||
 | 
					    {0x22, 0},          /* 5 */
 | 
				
			||||||
 | 
					    {0x23, 0},          /* 6 */
 | 
				
			||||||
 | 
					    {0x24, 0},          /* 7 */
 | 
				
			||||||
 | 
					    {0x25, 0},          /* 8 */
 | 
				
			||||||
 | 
					    {0x26, 0},          /* 9 */
 | 
				
			||||||
 | 
					    {0x33, KEY_SHIFT},      /* : */
 | 
				
			||||||
 | 
					    {0x33, 0},          /* ; */
 | 
				
			||||||
 | 
					    {0x36, KEY_SHIFT},      /* < */
 | 
				
			||||||
 | 
					    {0x2e, 0},          /* = */
 | 
				
			||||||
 | 
					    {0x37, KEY_SHIFT},      /* > */
 | 
				
			||||||
 | 
					    {0x38, KEY_SHIFT},      /* ? */
 | 
				
			||||||
 | 
					    {0x34, KEY_SHIFT},      /* @ */
 | 
				
			||||||
 | 
					    {0x04, KEY_SHIFT},      /* A */
 | 
				
			||||||
 | 
					    {0x05, KEY_SHIFT},      /* B */
 | 
				
			||||||
 | 
					    {0x06, KEY_SHIFT},      /* C */
 | 
				
			||||||
 | 
					    {0x07, KEY_SHIFT},      /* D */
 | 
				
			||||||
 | 
					    {0x08, KEY_SHIFT},      /* E */
 | 
				
			||||||
 | 
					    {0x09, KEY_SHIFT},      /* F */
 | 
				
			||||||
 | 
					    {0x0a, KEY_SHIFT},      /* G */
 | 
				
			||||||
 | 
					    {0x0b, KEY_SHIFT},      /* H */
 | 
				
			||||||
 | 
					    {0x0c, KEY_SHIFT},      /* I */
 | 
				
			||||||
 | 
					    {0x0d, KEY_SHIFT},      /* J */
 | 
				
			||||||
 | 
					    {0x0e, KEY_SHIFT},      /* K */
 | 
				
			||||||
 | 
					    {0x0f, KEY_SHIFT},      /* L */
 | 
				
			||||||
 | 
					    {0x10, KEY_SHIFT},      /* M */
 | 
				
			||||||
 | 
					    {0x11, KEY_SHIFT},      /* N */
 | 
				
			||||||
 | 
					    {0x12, KEY_SHIFT},      /* O */
 | 
				
			||||||
 | 
					    {0x13, KEY_SHIFT},      /* P */
 | 
				
			||||||
 | 
					    {0x14, KEY_SHIFT},      /* Q */
 | 
				
			||||||
 | 
					    {0x15, KEY_SHIFT},      /* R */
 | 
				
			||||||
 | 
					    {0x16, KEY_SHIFT},      /* S */
 | 
				
			||||||
 | 
					    {0x17, KEY_SHIFT},      /* T */
 | 
				
			||||||
 | 
					    {0x18, KEY_SHIFT},      /* U */
 | 
				
			||||||
 | 
					    {0x19, KEY_SHIFT},      /* V */
 | 
				
			||||||
 | 
					    {0x1a, KEY_SHIFT},      /* W */
 | 
				
			||||||
 | 
					    {0x1b, KEY_SHIFT},      /* X */
 | 
				
			||||||
 | 
					    {0x1c, KEY_SHIFT},      /* Y */
 | 
				
			||||||
 | 
					    {0x1d, KEY_SHIFT},      /* Z */
 | 
				
			||||||
 | 
					    {0x2f, 0},          /* [ */
 | 
				
			||||||
 | 
					    {0x64, 0},          /* \ */
 | 
				
			||||||
 | 
					    {0x30, 0},          /* ] */
 | 
				
			||||||
 | 
					    {0x23, KEY_SHIFT},      /* ^ */
 | 
				
			||||||
 | 
					    {0x2d, KEY_SHIFT},      /* _ */
 | 
				
			||||||
 | 
					    {0x35, 0},          /* ` */
 | 
				
			||||||
 | 
					    {0x04, 0},          /* a */
 | 
				
			||||||
 | 
					    {0x05, 0},          /* b */
 | 
				
			||||||
 | 
					    {0x06, 0},          /* c */
 | 
				
			||||||
 | 
					    {0x07, 0},          /* d */
 | 
				
			||||||
 | 
					    {0x08, 0},          /* e */
 | 
				
			||||||
 | 
					    {0x09, 0},          /* f */
 | 
				
			||||||
 | 
					    {0x0a, 0},          /* g */
 | 
				
			||||||
 | 
					    {0x0b, 0},          /* h */
 | 
				
			||||||
 | 
					    {0x0c, 0},          /* i */
 | 
				
			||||||
 | 
					    {0x0d, 0},          /* j */
 | 
				
			||||||
 | 
					    {0x0e, 0},          /* k */
 | 
				
			||||||
 | 
					    {0x0f, 0},          /* l */
 | 
				
			||||||
 | 
					    {0x10, 0},          /* m */
 | 
				
			||||||
 | 
					    {0x11, 0},          /* n */
 | 
				
			||||||
 | 
					    {0x12, 0},          /* o */
 | 
				
			||||||
 | 
					    {0x13, 0},          /* p */
 | 
				
			||||||
 | 
					    {0x14, 0},          /* q */
 | 
				
			||||||
 | 
					    {0x15, 0},          /* r */
 | 
				
			||||||
 | 
					    {0x16, 0},          /* s */
 | 
				
			||||||
 | 
					    {0x17, 0},          /* t */
 | 
				
			||||||
 | 
					    {0x18, 0},          /* u */
 | 
				
			||||||
 | 
					    {0x19, 0},          /* v */
 | 
				
			||||||
 | 
					    {0x1a, 0},          /* w */
 | 
				
			||||||
 | 
					    {0x1b, 0},          /* x */
 | 
				
			||||||
 | 
					    {0x1c, 0},          /* y */
 | 
				
			||||||
 | 
					    {0x1d, 0},          /* z */
 | 
				
			||||||
 | 
					    {0x2f, KEY_SHIFT},      /* { */
 | 
				
			||||||
 | 
					    {0x64, KEY_SHIFT},      /* | */
 | 
				
			||||||
 | 
					    {0x30, KEY_SHIFT},      /* } */
 | 
				
			||||||
 | 
					    {0x32, KEY_SHIFT},      /* ~ */
 | 
				
			||||||
 | 
					    {0,0},             /* DEL */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    {0x3a, 0},          /* F1 */
 | 
				
			||||||
 | 
					    {0x3b, 0},          /* F2 */
 | 
				
			||||||
 | 
					    {0x3c, 0},          /* F3 */
 | 
				
			||||||
 | 
					    {0x3d, 0},          /* F4 */
 | 
				
			||||||
 | 
					    {0x3e, 0},          /* F5 */
 | 
				
			||||||
 | 
					    {0x3f, 0},          /* F6 */
 | 
				
			||||||
 | 
					    {0x40, 0},          /* F7 */
 | 
				
			||||||
 | 
					    {0x41, 0},          /* F8 */
 | 
				
			||||||
 | 
					    {0x42, 0},          /* F9 */
 | 
				
			||||||
 | 
					    {0x43, 0},          /* F10 */
 | 
				
			||||||
 | 
					    {0x44, 0},          /* F11 */
 | 
				
			||||||
 | 
					    {0x45, 0},          /* F12 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    {0x46, 0},          /* PRINT_SCREEN */
 | 
				
			||||||
 | 
					    {0x47, 0},          /* SCROLL_LOCK */
 | 
				
			||||||
 | 
					    {0x39, 0},          /* CAPS_LOCK */
 | 
				
			||||||
 | 
					    {0x53, 0},          /* NUM_LOCK */
 | 
				
			||||||
 | 
					    {0x49, 0},          /* INSERT */
 | 
				
			||||||
 | 
					    {0x4a, 0},          /* HOME */
 | 
				
			||||||
 | 
					    {0x4b, 0},          /* PAGE_UP */
 | 
				
			||||||
 | 
					    {0x4e, 0},          /* PAGE_DOWN */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    {0x4f, 0},          /* RIGHT_ARROW */
 | 
				
			||||||
 | 
					    {0x50, 0},          /* LEFT_ARROW */
 | 
				
			||||||
 | 
					    {0x51, 0},          /* DOWN_ARROW */
 | 
				
			||||||
 | 
					    {0x52, 0},          /* UP_ARROW */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										91
									
								
								src/components/esp-nimble-cpp-1.3.3/src/HIDTypes.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								src/components/esp-nimble-cpp-1.3.3/src/HIDTypes.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,91 @@
 | 
				
			|||||||
 | 
					/* Copyright (c) 2010-2011 mbed.org, MIT License
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* 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 USBCLASS_HID_TYPES
 | 
				
			||||||
 | 
					#define USBCLASS_HID_TYPES
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* */
 | 
				
			||||||
 | 
					#define HID_VERSION_1_11    (0x0111)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* HID Class */
 | 
				
			||||||
 | 
					#define HID_CLASS           (3)
 | 
				
			||||||
 | 
					#define HID_SUBCLASS_NONE   (0)
 | 
				
			||||||
 | 
					#define HID_PROTOCOL_NONE   (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Descriptors */
 | 
				
			||||||
 | 
					#define HID_DESCRIPTOR          (33)
 | 
				
			||||||
 | 
					#define HID_DESCRIPTOR_LENGTH   (0x09)
 | 
				
			||||||
 | 
					#define REPORT_DESCRIPTOR       (34)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Class requests */
 | 
				
			||||||
 | 
					#define GET_REPORT (0x1)
 | 
				
			||||||
 | 
					#define GET_IDLE   (0x2)
 | 
				
			||||||
 | 
					#define SET_REPORT (0x9)
 | 
				
			||||||
 | 
					#define SET_IDLE   (0xa)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* HID Class Report Descriptor */
 | 
				
			||||||
 | 
					/* Short items: size is 0, 1, 2 or 3 specifying 0, 1, 2 or 4 (four) bytes */
 | 
				
			||||||
 | 
					/* of data as per HID Class standard */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Main items */
 | 
				
			||||||
 | 
					#define HIDINPUT(size)          (0x80 | size)
 | 
				
			||||||
 | 
					#define HIDOUTPUT(size)         (0x90 | size)
 | 
				
			||||||
 | 
					#define FEATURE(size)           (0xb0 | size)
 | 
				
			||||||
 | 
					#define COLLECTION(size)        (0xa0 | size)
 | 
				
			||||||
 | 
					#define END_COLLECTION(size)    (0xc0 | size)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Global items */
 | 
				
			||||||
 | 
					#define USAGE_PAGE(size)        (0x04 | size)
 | 
				
			||||||
 | 
					#define LOGICAL_MINIMUM(size)   (0x14 | size)
 | 
				
			||||||
 | 
					#define LOGICAL_MAXIMUM(size)   (0x24 | size)
 | 
				
			||||||
 | 
					#define PHYSICAL_MINIMUM(size)  (0x34 | size)
 | 
				
			||||||
 | 
					#define PHYSICAL_MAXIMUM(size)  (0x44 | size)
 | 
				
			||||||
 | 
					#define UNIT_EXPONENT(size)     (0x54 | size)
 | 
				
			||||||
 | 
					#define UNIT(size)              (0x64 | size)
 | 
				
			||||||
 | 
					#define REPORT_SIZE(size)       (0x74 | size)  //bits
 | 
				
			||||||
 | 
					#define REPORT_ID(size)         (0x84 | size)
 | 
				
			||||||
 | 
					#define REPORT_COUNT(size)      (0x94 | size)  //bytes
 | 
				
			||||||
 | 
					#define PUSH(size)              (0xa4 | size)
 | 
				
			||||||
 | 
					#define POP(size)               (0xb4 | size)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Local items */
 | 
				
			||||||
 | 
					#define USAGE(size)                 (0x08 | size)
 | 
				
			||||||
 | 
					#define USAGE_MINIMUM(size)         (0x18 | size)
 | 
				
			||||||
 | 
					#define USAGE_MAXIMUM(size)         (0x28 | size)
 | 
				
			||||||
 | 
					#define DESIGNATOR_INDEX(size)      (0x38 | size)
 | 
				
			||||||
 | 
					#define DESIGNATOR_MINIMUM(size)    (0x48 | size)
 | 
				
			||||||
 | 
					#define DESIGNATOR_MAXIMUM(size)    (0x58 | size)
 | 
				
			||||||
 | 
					#define STRING_INDEX(size)          (0x78 | size)
 | 
				
			||||||
 | 
					#define STRING_MINIMUM(size)        (0x88 | size)
 | 
				
			||||||
 | 
					#define STRING_MAXIMUM(size)        (0x98 | size)
 | 
				
			||||||
 | 
					#define DELIMITER(size)             (0xa8 | size)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* HID Report */
 | 
				
			||||||
 | 
					/* Where report IDs are used the first byte of 'data' will be the */
 | 
				
			||||||
 | 
					/* report ID and 'length' will include this report ID byte. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MAX_HID_REPORT_SIZE (64)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					    uint32_t length;
 | 
				
			||||||
 | 
					    uint8_t data[MAX_HID_REPORT_SIZE];
 | 
				
			||||||
 | 
					} HID_REPORT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										86
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLE2904.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLE2904.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,86 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * NimBLE2904.cpp
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created: on March 13, 2020
 | 
				
			||||||
 | 
					 *      Author H2zero
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Originally:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * BLE2904.cpp
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created on: Dec 23, 2017
 | 
				
			||||||
 | 
					 *      Author: kolban
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * See also:
 | 
				
			||||||
 | 
					 * https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.characteristic_presentation_format.xml
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#include "nimconfig.h"
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "NimBLE2904.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NimBLE2904::NimBLE2904(NimBLECharacteristic* pCharacterisitic)
 | 
				
			||||||
 | 
					: NimBLEDescriptor(NimBLEUUID((uint16_t) 0x2904),
 | 
				
			||||||
 | 
					                            BLE_GATT_CHR_F_READ,
 | 
				
			||||||
 | 
					                            sizeof(BLE2904_Data),
 | 
				
			||||||
 | 
					                            pCharacterisitic)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    m_data.m_format      = 0;
 | 
				
			||||||
 | 
					    m_data.m_exponent    = 0;
 | 
				
			||||||
 | 
					    m_data.m_namespace   = 1;  // 1 = Bluetooth SIG Assigned Numbers
 | 
				
			||||||
 | 
					    m_data.m_unit        = 0;
 | 
				
			||||||
 | 
					    m_data.m_description = 0;
 | 
				
			||||||
 | 
					    setValue((uint8_t*) &m_data, sizeof(m_data));
 | 
				
			||||||
 | 
					} // BLE2904
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set the description.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLE2904::setDescription(uint16_t description) {
 | 
				
			||||||
 | 
					    m_data.m_description = description;
 | 
				
			||||||
 | 
					    setValue((uint8_t*) &m_data, sizeof(m_data));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set the exponent.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLE2904::setExponent(int8_t exponent) {
 | 
				
			||||||
 | 
					    m_data.m_exponent = exponent;
 | 
				
			||||||
 | 
					    setValue((uint8_t*) &m_data, sizeof(m_data));
 | 
				
			||||||
 | 
					} // setExponent
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set the format.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLE2904::setFormat(uint8_t format) {
 | 
				
			||||||
 | 
					    m_data.m_format = format;
 | 
				
			||||||
 | 
					    setValue((uint8_t*) &m_data, sizeof(m_data));
 | 
				
			||||||
 | 
					} // setFormat
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set the namespace.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLE2904::setNamespace(uint8_t namespace_value) {
 | 
				
			||||||
 | 
					    m_data.m_namespace = namespace_value;
 | 
				
			||||||
 | 
					    setValue((uint8_t*) &m_data, sizeof(m_data));
 | 
				
			||||||
 | 
					} // setNamespace
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set the units for this value.  It should be one of the encoded values defined here:
 | 
				
			||||||
 | 
					 * https://www.bluetooth.com/specifications/assigned-numbers/units
 | 
				
			||||||
 | 
					 * @param [in] unit The type of units of this characteristic as defined by assigned numbers.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLE2904::setUnit(uint16_t unit) {
 | 
				
			||||||
 | 
					    m_data.m_unit = unit;
 | 
				
			||||||
 | 
					    setValue((uint8_t*) &m_data, sizeof(m_data));
 | 
				
			||||||
 | 
					} // setUnit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_PERIPHERAL */
 | 
				
			||||||
							
								
								
									
										83
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLE2904.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLE2904.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,83 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * NimBLE2904.h
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created: on March 13, 2020
 | 
				
			||||||
 | 
					 *      Author H2zero
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Originally:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * BLE2904.h
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created on: Dec 23, 2017
 | 
				
			||||||
 | 
					 *      Author: kolban
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef MAIN_NIMBLE2904_H_
 | 
				
			||||||
 | 
					#define MAIN_NIMBLE2904_H_
 | 
				
			||||||
 | 
					#include "nimconfig.h"
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "NimBLEDescriptor.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct BLE2904_Data {
 | 
				
			||||||
 | 
					    uint8_t  m_format;
 | 
				
			||||||
 | 
					    int8_t   m_exponent;
 | 
				
			||||||
 | 
					    uint16_t m_unit;      // See https://www.bluetooth.com/specifications/assigned-numbers/units
 | 
				
			||||||
 | 
					    uint8_t  m_namespace;
 | 
				
			||||||
 | 
					    uint16_t m_description;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} __attribute__((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Descriptor for Characteristic Presentation Format.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This is a convenience descriptor for the Characteristic Presentation Format which has a UUID of 0x2904.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * See also:
 | 
				
			||||||
 | 
					 * https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.characteristic_presentation_format.xml
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class NimBLE2904: public NimBLEDescriptor {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    NimBLE2904(NimBLECharacteristic* pCharacterisitic = nullptr);
 | 
				
			||||||
 | 
					    static const uint8_t FORMAT_BOOLEAN   = 1;
 | 
				
			||||||
 | 
					    static const uint8_t FORMAT_UINT2     = 2;
 | 
				
			||||||
 | 
					    static const uint8_t FORMAT_UINT4     = 3;
 | 
				
			||||||
 | 
					    static const uint8_t FORMAT_UINT8     = 4;
 | 
				
			||||||
 | 
					    static const uint8_t FORMAT_UINT12    = 5;
 | 
				
			||||||
 | 
					    static const uint8_t FORMAT_UINT16    = 6;
 | 
				
			||||||
 | 
					    static const uint8_t FORMAT_UINT24    = 7;
 | 
				
			||||||
 | 
					    static const uint8_t FORMAT_UINT32    = 8;
 | 
				
			||||||
 | 
					    static const uint8_t FORMAT_UINT48    = 9;
 | 
				
			||||||
 | 
					    static const uint8_t FORMAT_UINT64    = 10;
 | 
				
			||||||
 | 
					    static const uint8_t FORMAT_UINT128   = 11;
 | 
				
			||||||
 | 
					    static const uint8_t FORMAT_SINT8     = 12;
 | 
				
			||||||
 | 
					    static const uint8_t FORMAT_SINT12    = 13;
 | 
				
			||||||
 | 
					    static const uint8_t FORMAT_SINT16    = 14;
 | 
				
			||||||
 | 
					    static const uint8_t FORMAT_SINT24    = 15;
 | 
				
			||||||
 | 
					    static const uint8_t FORMAT_SINT32    = 16;
 | 
				
			||||||
 | 
					    static const uint8_t FORMAT_SINT48    = 17;
 | 
				
			||||||
 | 
					    static const uint8_t FORMAT_SINT64    = 18;
 | 
				
			||||||
 | 
					    static const uint8_t FORMAT_SINT128   = 19;
 | 
				
			||||||
 | 
					    static const uint8_t FORMAT_FLOAT32   = 20;
 | 
				
			||||||
 | 
					    static const uint8_t FORMAT_FLOAT64   = 21;
 | 
				
			||||||
 | 
					    static const uint8_t FORMAT_SFLOAT16  = 22;
 | 
				
			||||||
 | 
					    static const uint8_t FORMAT_SFLOAT32  = 23;
 | 
				
			||||||
 | 
					    static const uint8_t FORMAT_IEEE20601 = 24;
 | 
				
			||||||
 | 
					    static const uint8_t FORMAT_UTF8      = 25;
 | 
				
			||||||
 | 
					    static const uint8_t FORMAT_UTF16     = 26;
 | 
				
			||||||
 | 
					    static const uint8_t FORMAT_OPAQUE    = 27;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void setDescription(uint16_t);
 | 
				
			||||||
 | 
					    void setExponent(int8_t exponent);
 | 
				
			||||||
 | 
					    void setFormat(uint8_t format);
 | 
				
			||||||
 | 
					    void setNamespace(uint8_t namespace_value);
 | 
				
			||||||
 | 
					    void setUnit(uint16_t unit);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    friend class NimBLECharacteristic;
 | 
				
			||||||
 | 
					    BLE2904_Data m_data;
 | 
				
			||||||
 | 
					}; // BLE2904
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_PERIPHERAL */
 | 
				
			||||||
 | 
					#endif /* MAIN_NIMBLE2904_H_ */
 | 
				
			||||||
							
								
								
									
										197
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEAddress.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										197
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEAddress.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,197 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * NimBLEAddress.cpp
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created: on Jan 24 2020
 | 
				
			||||||
 | 
					 *      Author H2zero
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Originally:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * BLEAddress.cpp
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created on: Jul 2, 2017
 | 
				
			||||||
 | 
					 *      Author: kolban
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#include "nimconfig.h"
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_ENABLED)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <algorithm>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "NimBLEAddress.h"
 | 
				
			||||||
 | 
					#include "NimBLEUtils.h"
 | 
				
			||||||
 | 
					#include "NimBLELog.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char* LOG_TAG = "NimBLEAddress";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*************************************************
 | 
				
			||||||
 | 
					 * NOTE: NimBLE address bytes are in INVERSE ORDER!
 | 
				
			||||||
 | 
					 * We will accomodate that fact in these methods.
 | 
				
			||||||
 | 
					*************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Create an address from the native NimBLE representation.
 | 
				
			||||||
 | 
					 * @param [in] address The native NimBLE address.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEAddress::NimBLEAddress(ble_addr_t address) {
 | 
				
			||||||
 | 
					    memcpy(m_address, address.val, 6);
 | 
				
			||||||
 | 
					    m_addrType = address.type;
 | 
				
			||||||
 | 
					} // NimBLEAddress
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Create a blank address, i.e. 00:00:00:00:00:00, type 0.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEAddress::NimBLEAddress() {
 | 
				
			||||||
 | 
					    NimBLEAddress("");
 | 
				
			||||||
 | 
					} // NimBLEAddress
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Create an address from a hex string
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * A hex string is of the format:
 | 
				
			||||||
 | 
					 * ```
 | 
				
			||||||
 | 
					 * 00:00:00:00:00:00
 | 
				
			||||||
 | 
					 * ```
 | 
				
			||||||
 | 
					 * which is 17 characters in length.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param [in] stringAddress The hex string representation of the address.
 | 
				
			||||||
 | 
					 * @param [in] type The type of the address.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEAddress::NimBLEAddress(const std::string &stringAddress, uint8_t type) {
 | 
				
			||||||
 | 
					    m_addrType = type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (stringAddress.length() == 0) {
 | 
				
			||||||
 | 
					        memset(m_address, 0, 6);
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (stringAddress.length() == 6) {
 | 
				
			||||||
 | 
					        std::reverse_copy(stringAddress.data(), stringAddress.data() + 6, m_address);
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (stringAddress.length() != 17) {
 | 
				
			||||||
 | 
					        memset(m_address, 0, sizeof m_address); // "00:00:00:00:00:00" represents an invalid address
 | 
				
			||||||
 | 
					        NIMBLE_LOGD(LOG_TAG, "Invalid address '%s'", stringAddress.c_str());
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int data[6];
 | 
				
			||||||
 | 
					    if(sscanf(stringAddress.c_str(), "%x:%x:%x:%x:%x:%x", &data[5], &data[4], &data[3], &data[2], &data[1], &data[0]) != 6) {
 | 
				
			||||||
 | 
					        memset(m_address, 0, sizeof m_address); // "00:00:00:00:00:00" represents an invalid address
 | 
				
			||||||
 | 
					        NIMBLE_LOGD(LOG_TAG, "Invalid address '%s'", stringAddress.c_str());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    for(size_t index = 0; index < sizeof m_address; index++) {
 | 
				
			||||||
 | 
					        m_address[index] = data[index];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					} // NimBLEAddress
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Constructor for compatibility with bluedroid esp library using native ESP representation.
 | 
				
			||||||
 | 
					 * @param [in] address A uint8_t[6] or esp_bd_addr_t containing the address.
 | 
				
			||||||
 | 
					 * @param [in] type The type of the address.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEAddress::NimBLEAddress(uint8_t address[6], uint8_t type) {
 | 
				
			||||||
 | 
					    std::reverse_copy(address, address + sizeof m_address, m_address);
 | 
				
			||||||
 | 
					    m_addrType = type;
 | 
				
			||||||
 | 
					} // NimBLEAddress
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Constructor for address using a hex value.\n
 | 
				
			||||||
 | 
					 * Use the same byte order, so use 0xa4c1385def16 for "a4:c1:38:5d:ef:16"
 | 
				
			||||||
 | 
					 * @param [in] address uint64_t containing the address.
 | 
				
			||||||
 | 
					 * @param [in] type The type of the address.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEAddress::NimBLEAddress(const uint64_t &address, uint8_t type) {
 | 
				
			||||||
 | 
					    memcpy(m_address, &address, sizeof m_address);
 | 
				
			||||||
 | 
					    m_addrType = type;
 | 
				
			||||||
 | 
					} // NimBLEAddress
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Determine if this address equals another.
 | 
				
			||||||
 | 
					 * @param [in] otherAddress The other address to compare against.
 | 
				
			||||||
 | 
					 * @return True if the addresses are equal.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool NimBLEAddress::equals(const NimBLEAddress &otherAddress) const {
 | 
				
			||||||
 | 
					    return *this == otherAddress;
 | 
				
			||||||
 | 
					} // equals
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the native representation of the address.
 | 
				
			||||||
 | 
					 * @return a pointer to the uint8_t[6] array of the address.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					const uint8_t *NimBLEAddress::getNative() const {
 | 
				
			||||||
 | 
					    return m_address;
 | 
				
			||||||
 | 
					} // getNative
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the address type.
 | 
				
			||||||
 | 
					 * @return The address type.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint8_t NimBLEAddress::getType() const {
 | 
				
			||||||
 | 
					    return m_addrType;
 | 
				
			||||||
 | 
					} // getType
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Convert a BLE address to a string.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * A string representation of an address is in the format:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * ```
 | 
				
			||||||
 | 
					 * xx:xx:xx:xx:xx:xx
 | 
				
			||||||
 | 
					 * ```
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @return The string representation of the address.
 | 
				
			||||||
 | 
					 * @deprecated Use std::string() operator instead.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					std::string NimBLEAddress::toString() const {
 | 
				
			||||||
 | 
					    return std::string(*this);
 | 
				
			||||||
 | 
					} // toString
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Convienience operator to check if this address is equal to another.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool NimBLEAddress::operator ==(const NimBLEAddress & rhs) const {
 | 
				
			||||||
 | 
					    return memcmp(rhs.m_address, m_address, sizeof m_address) == 0;
 | 
				
			||||||
 | 
					} // operator ==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Convienience operator to check if this address is not equal to another.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool NimBLEAddress::operator !=(const NimBLEAddress & rhs) const {
 | 
				
			||||||
 | 
					    return !this->operator==(rhs);
 | 
				
			||||||
 | 
					} // operator !=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Convienience operator to convert this address to string representation.
 | 
				
			||||||
 | 
					 * @details This allows passing NimBLEAddress to functions
 | 
				
			||||||
 | 
					 * that accept std::string and/or or it's methods as a parameter.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEAddress::operator std::string() const {
 | 
				
			||||||
 | 
					    char buffer[18];
 | 
				
			||||||
 | 
					    snprintf(buffer, sizeof(buffer), "%02x:%02x:%02x:%02x:%02x:%02x",
 | 
				
			||||||
 | 
					                                     m_address[5], m_address[4], m_address[3],
 | 
				
			||||||
 | 
					                                     m_address[2], m_address[1], m_address[0]);
 | 
				
			||||||
 | 
					    return std::string(buffer);
 | 
				
			||||||
 | 
					} // operator std::string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Convienience operator to convert the native address representation to uint_64.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEAddress::operator uint64_t() const {
 | 
				
			||||||
 | 
					    uint64_t address = 0;
 | 
				
			||||||
 | 
					    memcpy(&address, m_address, sizeof m_address);
 | 
				
			||||||
 | 
					    return address;
 | 
				
			||||||
 | 
					} // operator uint64_t
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										62
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEAddress.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEAddress.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * NimBLEAddress.h
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created: on Jan 24 2020
 | 
				
			||||||
 | 
					 *      Author H2zero
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Originally:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * BLEAddress.h
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created on: Jul 2, 2017
 | 
				
			||||||
 | 
					 *      Author: kolban
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef COMPONENTS_NIMBLEADDRESS_H_
 | 
				
			||||||
 | 
					#define COMPONENTS_NIMBLEADDRESS_H_
 | 
				
			||||||
 | 
					#include "nimconfig.h"
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_ENABLED)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(CONFIG_NIMBLE_CPP_IDF)
 | 
				
			||||||
 | 
					#include "nimble/ble.h"
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#include "nimble/nimble/include/nimble/ble.h"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/****  FIX COMPILATION ****/
 | 
				
			||||||
 | 
					#undef min
 | 
				
			||||||
 | 
					#undef max
 | 
				
			||||||
 | 
					/**************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					#include <algorithm>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief A %BLE device address.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Every %BLE device has a unique address which can be used to identify it and form connections.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class NimBLEAddress {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    NimBLEAddress();
 | 
				
			||||||
 | 
					    NimBLEAddress(ble_addr_t address);
 | 
				
			||||||
 | 
					    NimBLEAddress(uint8_t address[6], uint8_t type = BLE_ADDR_PUBLIC);
 | 
				
			||||||
 | 
					    NimBLEAddress(const std::string &stringAddress, uint8_t type = BLE_ADDR_PUBLIC);
 | 
				
			||||||
 | 
					    NimBLEAddress(const uint64_t &address, uint8_t type = BLE_ADDR_PUBLIC);
 | 
				
			||||||
 | 
					    bool            equals(const NimBLEAddress &otherAddress) const;
 | 
				
			||||||
 | 
					    const uint8_t*  getNative() const;
 | 
				
			||||||
 | 
					    std::string     toString() const;
 | 
				
			||||||
 | 
					    uint8_t         getType() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool operator   ==(const NimBLEAddress & rhs) const;
 | 
				
			||||||
 | 
					    bool operator   !=(const NimBLEAddress & rhs) const;
 | 
				
			||||||
 | 
					    operator        std::string() const;
 | 
				
			||||||
 | 
					    operator        uint64_t() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    uint8_t        m_address[6];
 | 
				
			||||||
 | 
					    uint8_t        m_addrType;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* CONFIG_BT_ENABLED */
 | 
				
			||||||
 | 
					#endif /* COMPONENTS_NIMBLEADDRESS_H_ */
 | 
				
			||||||
@@ -0,0 +1,785 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * NimBLEAdvertisedDevice.cpp
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created: on Jan 24 2020
 | 
				
			||||||
 | 
					 *      Author H2zero
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Originally:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  BLEAdvertisedDevice.cpp
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created on: Jul 3, 2017
 | 
				
			||||||
 | 
					 *      Author: kolban
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "nimconfig.h"
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "NimBLEDevice.h"
 | 
				
			||||||
 | 
					#include "NimBLEAdvertisedDevice.h"
 | 
				
			||||||
 | 
					#include "NimBLEUtils.h"
 | 
				
			||||||
 | 
					#include "NimBLELog.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char* LOG_TAG = "NimBLEAdvertisedDevice";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Constructor
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEAdvertisedDevice::NimBLEAdvertisedDevice() :
 | 
				
			||||||
 | 
					    m_payload(62,0)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    m_advType          = 0;
 | 
				
			||||||
 | 
					    m_rssi             = -9999;
 | 
				
			||||||
 | 
					    m_callbackSent     = false;
 | 
				
			||||||
 | 
					    m_timestamp        = 0;
 | 
				
			||||||
 | 
					    m_advLength        = 0;
 | 
				
			||||||
 | 
					} // NimBLEAdvertisedDevice
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the address of the advertising device.
 | 
				
			||||||
 | 
					 * @return The address of the advertised device.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEAddress NimBLEAdvertisedDevice::getAddress() {
 | 
				
			||||||
 | 
					    return m_address;
 | 
				
			||||||
 | 
					} // getAddress
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the advertisement type.
 | 
				
			||||||
 | 
					 * @return The advertising type the device is reporting:
 | 
				
			||||||
 | 
					 * * BLE_HCI_ADV_TYPE_ADV_IND            (0) - indirect advertising
 | 
				
			||||||
 | 
					 * * BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD  (1) - direct advertisng - high duty cycle
 | 
				
			||||||
 | 
					 * * BLE_HCI_ADV_TYPE_ADV_SCAN_IND       (2) - indirect scan response
 | 
				
			||||||
 | 
					 * * BLE_HCI_ADV_TYPE_ADV_NONCONN_IND    (3) - indirect advertisng - not connectable
 | 
				
			||||||
 | 
					 * * BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_LD  (4) - direct advertising - low duty cycle
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint8_t NimBLEAdvertisedDevice::getAdvType() {
 | 
				
			||||||
 | 
					    return m_advType;
 | 
				
			||||||
 | 
					} // getAdvType
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the appearance.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * A %BLE device can declare its own appearance.  The appearance is how it would like to be shown to an end user
 | 
				
			||||||
 | 
					 * typcially in the form of an icon.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @return The appearance of the advertised device.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint16_t NimBLEAdvertisedDevice::getAppearance() {
 | 
				
			||||||
 | 
					    uint8_t data_loc = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(findAdvField(BLE_HS_ADV_TYPE_APPEARANCE, 0, &data_loc) > 0) {
 | 
				
			||||||
 | 
					        ble_hs_adv_field *field = (ble_hs_adv_field *)&m_payload[data_loc];
 | 
				
			||||||
 | 
					        if(field->length == BLE_HS_ADV_APPEARANCE_LEN + 1) {
 | 
				
			||||||
 | 
					            return *field->value | *(field->value + 1) << 8;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					} // getAppearance
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the advertisement interval.
 | 
				
			||||||
 | 
					 * @return The advertisement interval in 0.625ms units.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint16_t NimBLEAdvertisedDevice::getAdvInterval() {
 | 
				
			||||||
 | 
					    uint8_t data_loc = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(findAdvField(BLE_HS_ADV_TYPE_ADV_ITVL, 0, &data_loc) > 0) {
 | 
				
			||||||
 | 
					        ble_hs_adv_field *field = (ble_hs_adv_field *)&m_payload[data_loc];
 | 
				
			||||||
 | 
					        if(field->length == BLE_HS_ADV_ADV_ITVL_LEN + 1) {
 | 
				
			||||||
 | 
					            return *field->value | *(field->value + 1) << 8;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					} // getAdvInterval
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the preferred min connection interval.
 | 
				
			||||||
 | 
					 * @return The preferred min connection interval in 1.25ms units.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint16_t NimBLEAdvertisedDevice::getMinInterval() {
 | 
				
			||||||
 | 
					    uint8_t data_loc = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(findAdvField(BLE_HS_ADV_TYPE_SLAVE_ITVL_RANGE, 0, &data_loc) > 0) {
 | 
				
			||||||
 | 
					        ble_hs_adv_field *field = (ble_hs_adv_field *)&m_payload[data_loc];
 | 
				
			||||||
 | 
					        if(field->length == BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN + 1) {
 | 
				
			||||||
 | 
					            return *field->value | *(field->value + 1) << 8;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					} // getMinInterval
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the preferred max connection interval.
 | 
				
			||||||
 | 
					 * @return The preferred max connection interval in 1.25ms units.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint16_t NimBLEAdvertisedDevice::getMaxInterval() {
 | 
				
			||||||
 | 
					    uint8_t data_loc = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(findAdvField(BLE_HS_ADV_TYPE_SLAVE_ITVL_RANGE, 0, &data_loc) > 0) {
 | 
				
			||||||
 | 
					        ble_hs_adv_field *field = (ble_hs_adv_field *)&m_payload[data_loc];
 | 
				
			||||||
 | 
					        if(field->length == BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN + 1) {
 | 
				
			||||||
 | 
					            return *(field->value + 2) | *(field->value + 3) << 8;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					} // getMaxInterval
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the manufacturer data.
 | 
				
			||||||
 | 
					 * @return The manufacturer data of the advertised device.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					std::string NimBLEAdvertisedDevice::getManufacturerData() {
 | 
				
			||||||
 | 
					    uint8_t data_loc = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(findAdvField(BLE_HS_ADV_TYPE_MFG_DATA, 0, &data_loc) > 0) {
 | 
				
			||||||
 | 
					        ble_hs_adv_field *field = (ble_hs_adv_field *)&m_payload[data_loc];
 | 
				
			||||||
 | 
					        if(field->length > 1) {
 | 
				
			||||||
 | 
					            return std::string((char*)field->value, field->length - 1);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return "";
 | 
				
			||||||
 | 
					} // getManufacturerData
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the URI from the advertisement.
 | 
				
			||||||
 | 
					 * @return The URI data.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					std::string NimBLEAdvertisedDevice::getURI() {
 | 
				
			||||||
 | 
					    uint8_t data_loc = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(findAdvField(BLE_HS_ADV_TYPE_URI, 0, &data_loc) > 0) {
 | 
				
			||||||
 | 
					        ble_hs_adv_field *field = (ble_hs_adv_field *)&m_payload[data_loc];
 | 
				
			||||||
 | 
					        if(field->length > 1) {
 | 
				
			||||||
 | 
					            return std::string((char*)field->value, field->length - 1);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return "";
 | 
				
			||||||
 | 
					} // getURI
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the advertised name.
 | 
				
			||||||
 | 
					 * @return The name of the advertised device.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					std::string NimBLEAdvertisedDevice::getName() {
 | 
				
			||||||
 | 
					    uint8_t data_loc = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(findAdvField(BLE_HS_ADV_TYPE_COMP_NAME, 0, &data_loc) > 0 ||
 | 
				
			||||||
 | 
					       findAdvField(BLE_HS_ADV_TYPE_INCOMP_NAME, 0, &data_loc) > 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ble_hs_adv_field *field = (ble_hs_adv_field *)&m_payload[data_loc];
 | 
				
			||||||
 | 
					        if(field->length > 1) {
 | 
				
			||||||
 | 
					            return std::string((char*)field->value, field->length - 1);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return "";
 | 
				
			||||||
 | 
					} // getName
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the RSSI.
 | 
				
			||||||
 | 
					 * @return The RSSI of the advertised device.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int NimBLEAdvertisedDevice::getRSSI() {
 | 
				
			||||||
 | 
					    return m_rssi;
 | 
				
			||||||
 | 
					} // getRSSI
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the scan object that created this advertised device.
 | 
				
			||||||
 | 
					 * @return The scan object.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEScan* NimBLEAdvertisedDevice::getScan() {
 | 
				
			||||||
 | 
					    return NimBLEDevice::getScan();
 | 
				
			||||||
 | 
					} // getScan
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the number of target addresses.
 | 
				
			||||||
 | 
					 * @return The number of addresses.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					size_t NimBLEAdvertisedDevice::getTargetAddressCount() {
 | 
				
			||||||
 | 
					    uint8_t count = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    count = findAdvField(BLE_HS_ADV_TYPE_PUBLIC_TGT_ADDR);
 | 
				
			||||||
 | 
					    count += findAdvField(BLE_HS_ADV_TYPE_RANDOM_TGT_ADDR);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return count;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the target address at the index.
 | 
				
			||||||
 | 
					 * @param [in] index The index of the target address.
 | 
				
			||||||
 | 
					 * @return The target address.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEAddress NimBLEAdvertisedDevice::getTargetAddress(uint8_t index) {
 | 
				
			||||||
 | 
					    ble_hs_adv_field *field = nullptr;
 | 
				
			||||||
 | 
					    uint8_t count = 0;
 | 
				
			||||||
 | 
					    uint8_t data_loc = 0xFF;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    index++;
 | 
				
			||||||
 | 
					    count = findAdvField(BLE_HS_ADV_TYPE_PUBLIC_TGT_ADDR, index, &data_loc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (count < index) {
 | 
				
			||||||
 | 
					        index -= count;
 | 
				
			||||||
 | 
					        count = findAdvField(BLE_HS_ADV_TYPE_RANDOM_TGT_ADDR, index, &data_loc);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(count > 0 && data_loc != 0xFF) {
 | 
				
			||||||
 | 
					        field = (ble_hs_adv_field *)&m_payload[data_loc];
 | 
				
			||||||
 | 
					        if(field->length < index *  BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN) {
 | 
				
			||||||
 | 
					            index -= count - field->length / BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if(field->length > index * BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN) {
 | 
				
			||||||
 | 
					            return NimBLEAddress(field->value + (index - 1) * BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return NimBLEAddress("");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the service data.
 | 
				
			||||||
 | 
					 * @param [in] index The index of the service data requested.
 | 
				
			||||||
 | 
					 * @return The advertised service data or empty string if no data.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					std::string NimBLEAdvertisedDevice::getServiceData(uint8_t index) {
 | 
				
			||||||
 | 
					    ble_hs_adv_field *field = nullptr;
 | 
				
			||||||
 | 
					    uint8_t bytes;
 | 
				
			||||||
 | 
					    uint8_t data_loc = findServiceData(index, &bytes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(data_loc != 0xFF) {
 | 
				
			||||||
 | 
					        field = (ble_hs_adv_field *)&m_payload[data_loc];
 | 
				
			||||||
 | 
					        if(field->length > bytes) {
 | 
				
			||||||
 | 
					            return std::string((char*)(field->value + bytes), field->length - bytes - 1);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return "";
 | 
				
			||||||
 | 
					} //getServiceData
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the service data.
 | 
				
			||||||
 | 
					 * @param [in] uuid The uuid of the service data requested.
 | 
				
			||||||
 | 
					 * @return The advertised service data or empty string if no data.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					std::string NimBLEAdvertisedDevice::getServiceData(const NimBLEUUID &uuid) {
 | 
				
			||||||
 | 
					    ble_hs_adv_field *field = nullptr;
 | 
				
			||||||
 | 
					    uint8_t bytes;
 | 
				
			||||||
 | 
					    uint8_t index = 0;
 | 
				
			||||||
 | 
					    uint8_t data_loc = findServiceData(index, &bytes);
 | 
				
			||||||
 | 
					    uint8_t uuidBytes = uuid.bitSize() / 8;
 | 
				
			||||||
 | 
					    uint8_t plSize = m_payload.size() - 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while(data_loc < plSize) {
 | 
				
			||||||
 | 
					        field = (ble_hs_adv_field *)&m_payload[data_loc];
 | 
				
			||||||
 | 
					        if(bytes == uuidBytes && NimBLEUUID(field->value, bytes, false) == uuid) {
 | 
				
			||||||
 | 
					           return std::string((char*)(field->value + bytes), field->length - bytes - 1);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        index++;
 | 
				
			||||||
 | 
					        data_loc = findServiceData(index, &bytes);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NIMBLE_LOGI(LOG_TAG, "No service data found");
 | 
				
			||||||
 | 
					    return "";
 | 
				
			||||||
 | 
					} //getServiceData
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the UUID of the serice data at the index.
 | 
				
			||||||
 | 
					 * @param [in] index The index of the service data UUID requested.
 | 
				
			||||||
 | 
					 * @return The advertised service data UUID or an empty UUID if not found.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEUUID NimBLEAdvertisedDevice::getServiceDataUUID(uint8_t index) {
 | 
				
			||||||
 | 
					    ble_hs_adv_field *field = nullptr;
 | 
				
			||||||
 | 
					    uint8_t bytes;
 | 
				
			||||||
 | 
					    uint8_t data_loc = findServiceData(index, &bytes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(data_loc != 0xFF) {
 | 
				
			||||||
 | 
					        field = (ble_hs_adv_field *)&m_payload[data_loc];
 | 
				
			||||||
 | 
					        if(field->length >= bytes) {
 | 
				
			||||||
 | 
					            return NimBLEUUID(field->value, bytes, false);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return NimBLEUUID("");
 | 
				
			||||||
 | 
					} // getServiceDataUUID
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Find the service data at the index.
 | 
				
			||||||
 | 
					 * @param [in] index The index of the service data to find.
 | 
				
			||||||
 | 
					 * @param [in] bytes A pointer to storage for the number of the bytes in the UUID.
 | 
				
			||||||
 | 
					 * @return The index in the vector where the data is located, 0xFF if not found.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint8_t NimBLEAdvertisedDevice::findServiceData(uint8_t index, uint8_t *bytes) {
 | 
				
			||||||
 | 
					    uint8_t data_loc = 0;
 | 
				
			||||||
 | 
					    uint8_t found = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    *bytes = 0;
 | 
				
			||||||
 | 
					    index++;
 | 
				
			||||||
 | 
					    found = findAdvField(BLE_HS_ADV_TYPE_SVC_DATA_UUID16, index, &data_loc);
 | 
				
			||||||
 | 
					    if(found == index) {
 | 
				
			||||||
 | 
					        *bytes = 2;
 | 
				
			||||||
 | 
					        return data_loc;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    index -= found;
 | 
				
			||||||
 | 
					    found = findAdvField(BLE_HS_ADV_TYPE_SVC_DATA_UUID32, index, &data_loc);
 | 
				
			||||||
 | 
					    if(found == index) {
 | 
				
			||||||
 | 
					        *bytes = 4;
 | 
				
			||||||
 | 
					        return data_loc;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    index -= found;
 | 
				
			||||||
 | 
					    found = findAdvField(BLE_HS_ADV_TYPE_SVC_DATA_UUID128, index, &data_loc);
 | 
				
			||||||
 | 
					    if(found == index) {
 | 
				
			||||||
 | 
					        *bytes = 16;
 | 
				
			||||||
 | 
					        return data_loc;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0xFF;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the count of advertised service data UUIDS
 | 
				
			||||||
 | 
					 * @return The number of service data UUIDS in the vector.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					size_t NimBLEAdvertisedDevice::getServiceDataCount() {
 | 
				
			||||||
 | 
					    uint8_t count = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    count += findAdvField(BLE_HS_ADV_TYPE_SVC_DATA_UUID16);
 | 
				
			||||||
 | 
					    count += findAdvField(BLE_HS_ADV_TYPE_SVC_DATA_UUID32);
 | 
				
			||||||
 | 
					    count += findAdvField(BLE_HS_ADV_TYPE_SVC_DATA_UUID128);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return count;
 | 
				
			||||||
 | 
					} // getServiceDataCount
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the Service UUID.
 | 
				
			||||||
 | 
					 * @param [in] index The index of the service UUID requested.
 | 
				
			||||||
 | 
					 * @return The Service UUID of the advertised service, or an empty UUID if not found.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEUUID NimBLEAdvertisedDevice::getServiceUUID(uint8_t index) {
 | 
				
			||||||
 | 
					    uint8_t count = 0;
 | 
				
			||||||
 | 
					    uint8_t data_loc = 0;
 | 
				
			||||||
 | 
					    uint8_t uuidBytes = 0;
 | 
				
			||||||
 | 
					    uint8_t type = BLE_HS_ADV_TYPE_INCOMP_UUIDS16;
 | 
				
			||||||
 | 
					    ble_hs_adv_field *field = nullptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    index++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    do {
 | 
				
			||||||
 | 
					        count = findAdvField(type, index, &data_loc);
 | 
				
			||||||
 | 
					        if(count >= index) {
 | 
				
			||||||
 | 
					            if(type < BLE_HS_ADV_TYPE_INCOMP_UUIDS32) {
 | 
				
			||||||
 | 
					                uuidBytes = 2;
 | 
				
			||||||
 | 
					            } else if(type < BLE_HS_ADV_TYPE_INCOMP_UUIDS128) {
 | 
				
			||||||
 | 
					                uuidBytes = 4;
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                uuidBytes = 16;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            type++;
 | 
				
			||||||
 | 
					            index -= count;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    } while(type <= BLE_HS_ADV_TYPE_COMP_UUIDS128);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(uuidBytes > 0) {
 | 
				
			||||||
 | 
					        field = (ble_hs_adv_field *)&m_payload[data_loc];
 | 
				
			||||||
 | 
					        // In the case of more than one field of service uuid's we need to adjust
 | 
				
			||||||
 | 
					        // the index to account for the uuids of the previous fields.
 | 
				
			||||||
 | 
					        if(field->length < index * uuidBytes) {
 | 
				
			||||||
 | 
					            index -= count - field->length / uuidBytes;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(field->length > uuidBytes * index) {
 | 
				
			||||||
 | 
					            return NimBLEUUID(field->value + uuidBytes * (index - 1), uuidBytes, false);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return NimBLEUUID("");
 | 
				
			||||||
 | 
					} // getServiceUUID
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the number of services advertised
 | 
				
			||||||
 | 
					 * @return The count of services in the advertising packet.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					size_t NimBLEAdvertisedDevice::getServiceUUIDCount() {
 | 
				
			||||||
 | 
					    uint8_t count = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    count += findAdvField(BLE_HS_ADV_TYPE_INCOMP_UUIDS16);
 | 
				
			||||||
 | 
					    count += findAdvField(BLE_HS_ADV_TYPE_COMP_UUIDS16);
 | 
				
			||||||
 | 
					    count += findAdvField(BLE_HS_ADV_TYPE_INCOMP_UUIDS32);
 | 
				
			||||||
 | 
					    count += findAdvField(BLE_HS_ADV_TYPE_COMP_UUIDS32);
 | 
				
			||||||
 | 
					    count += findAdvField(BLE_HS_ADV_TYPE_INCOMP_UUIDS128);
 | 
				
			||||||
 | 
					    count += findAdvField(BLE_HS_ADV_TYPE_COMP_UUIDS128);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return count;
 | 
				
			||||||
 | 
					} // getServiceUUIDCount
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Check advertised services for existance of the required UUID
 | 
				
			||||||
 | 
					 * @param [in] uuid The service uuid to look for in the advertisement.
 | 
				
			||||||
 | 
					 * @return Return true if service is advertised
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool NimBLEAdvertisedDevice::isAdvertisingService(const NimBLEUUID &uuid) {
 | 
				
			||||||
 | 
					    size_t count = getServiceUUIDCount();
 | 
				
			||||||
 | 
					    for(size_t i = 0; i < count; i++) {
 | 
				
			||||||
 | 
					        if(uuid == getServiceUUID(i)) {
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					} // isAdvertisingService
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the TX Power.
 | 
				
			||||||
 | 
					 * @return The TX Power of the advertised device.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int8_t NimBLEAdvertisedDevice::getTXPower() {
 | 
				
			||||||
 | 
					    uint8_t data_loc = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(findAdvField(BLE_HS_ADV_TYPE_TX_PWR_LVL, 0, &data_loc) > 0) {
 | 
				
			||||||
 | 
					        ble_hs_adv_field *field = (ble_hs_adv_field *)&m_payload[data_loc];
 | 
				
			||||||
 | 
					        if(field->length == BLE_HS_ADV_TX_PWR_LVL_LEN + 1) {
 | 
				
			||||||
 | 
					            return *(int8_t*)field->value;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return -99;
 | 
				
			||||||
 | 
					} // getTXPower
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Does this advertisement have preferred connection parameters?
 | 
				
			||||||
 | 
					 * @return True if connection parameters are present.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool NimBLEAdvertisedDevice::haveConnParams() {
 | 
				
			||||||
 | 
					    return findAdvField(BLE_HS_ADV_TYPE_SLAVE_ITVL_RANGE) > 0;
 | 
				
			||||||
 | 
					} // haveConnParams
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Does this advertisement have have the advertising interval?
 | 
				
			||||||
 | 
					 * @return True if the advertisement interval is present.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool NimBLEAdvertisedDevice::haveAdvInterval() {
 | 
				
			||||||
 | 
					    return findAdvField(BLE_HS_ADV_TYPE_ADV_ITVL) > 0;
 | 
				
			||||||
 | 
					} // haveAdvInterval
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Does this advertisement have an appearance value?
 | 
				
			||||||
 | 
					 * @return True if there is an appearance value present.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool NimBLEAdvertisedDevice::haveAppearance() {
 | 
				
			||||||
 | 
					    return findAdvField(BLE_HS_ADV_TYPE_APPEARANCE) > 0;
 | 
				
			||||||
 | 
					} // haveAppearance
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Does this advertisement have manufacturer data?
 | 
				
			||||||
 | 
					 * @return True if there is manufacturer data present.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool NimBLEAdvertisedDevice::haveManufacturerData() {
 | 
				
			||||||
 | 
					    return findAdvField(BLE_HS_ADV_TYPE_MFG_DATA) > 0;
 | 
				
			||||||
 | 
					} // haveManufacturerData
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Does this advertisement have a URI?
 | 
				
			||||||
 | 
					 * @return True if there is a URI present.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool NimBLEAdvertisedDevice::haveURI() {
 | 
				
			||||||
 | 
					    return findAdvField(BLE_HS_ADV_TYPE_URI) > 0;
 | 
				
			||||||
 | 
					} // haveURI
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Does the advertisement contain a target address?
 | 
				
			||||||
 | 
					 * @return True if an address is present.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool NimBLEAdvertisedDevice::haveTargetAddress() {
 | 
				
			||||||
 | 
					    return findAdvField(BLE_HS_ADV_TYPE_PUBLIC_TGT_ADDR) > 0 ||
 | 
				
			||||||
 | 
					           findAdvField(BLE_HS_ADV_TYPE_RANDOM_TGT_ADDR) > 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Does this advertisement have a name value?
 | 
				
			||||||
 | 
					 * @return True if there is a name value present.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool NimBLEAdvertisedDevice::haveName() {
 | 
				
			||||||
 | 
					    return findAdvField(BLE_HS_ADV_TYPE_COMP_NAME) > 0 ||
 | 
				
			||||||
 | 
					           findAdvField(BLE_HS_ADV_TYPE_INCOMP_NAME) > 0;
 | 
				
			||||||
 | 
					} // haveName
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Does this advertisement have a signal strength value?
 | 
				
			||||||
 | 
					 * @return True if there is a signal strength value present.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool NimBLEAdvertisedDevice::haveRSSI() {
 | 
				
			||||||
 | 
					    return m_rssi != -9999;
 | 
				
			||||||
 | 
					} // haveRSSI
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Does this advertisement have a service data value?
 | 
				
			||||||
 | 
					 * @return True if there is a service data value present.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool NimBLEAdvertisedDevice::haveServiceData() {
 | 
				
			||||||
 | 
					    return getServiceDataCount() > 0;
 | 
				
			||||||
 | 
					} // haveServiceData
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Does this advertisement have a service UUID value?
 | 
				
			||||||
 | 
					 * @return True if there is a service UUID value present.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool NimBLEAdvertisedDevice::haveServiceUUID() {
 | 
				
			||||||
 | 
					    return getServiceUUIDCount() > 0;
 | 
				
			||||||
 | 
					} // haveServiceUUID
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Does this advertisement have a transmission power value?
 | 
				
			||||||
 | 
					 * @return True if there is a transmission power value present.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool NimBLEAdvertisedDevice::haveTXPower() {
 | 
				
			||||||
 | 
					    return findAdvField(BLE_HS_ADV_TYPE_TX_PWR_LVL) > 0;
 | 
				
			||||||
 | 
					} // haveTXPower
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint8_t NimBLEAdvertisedDevice::findAdvField(uint8_t type, uint8_t index, uint8_t *data_loc) {
 | 
				
			||||||
 | 
					    ble_hs_adv_field *field = nullptr;
 | 
				
			||||||
 | 
					    uint8_t data = 0;
 | 
				
			||||||
 | 
					    uint8_t length = m_payload.size();
 | 
				
			||||||
 | 
					    uint8_t count = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(length < 2) {
 | 
				
			||||||
 | 
					        return count;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while (length > 1) {
 | 
				
			||||||
 | 
					        field = (ble_hs_adv_field*)&m_payload[data];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (field->length >= length) {
 | 
				
			||||||
 | 
					            return count;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (field->type == type) {
 | 
				
			||||||
 | 
					            switch(type) {
 | 
				
			||||||
 | 
					                case BLE_HS_ADV_TYPE_INCOMP_UUIDS16:
 | 
				
			||||||
 | 
					                case BLE_HS_ADV_TYPE_COMP_UUIDS16:
 | 
				
			||||||
 | 
					                    count += field->length / 2;
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                case BLE_HS_ADV_TYPE_INCOMP_UUIDS32:
 | 
				
			||||||
 | 
					                case BLE_HS_ADV_TYPE_COMP_UUIDS32:
 | 
				
			||||||
 | 
					                    count += field->length / 4;
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                case BLE_HS_ADV_TYPE_INCOMP_UUIDS128:
 | 
				
			||||||
 | 
					                case BLE_HS_ADV_TYPE_COMP_UUIDS128:
 | 
				
			||||||
 | 
					                    count += field->length / 16;
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                case BLE_HS_ADV_TYPE_PUBLIC_TGT_ADDR:
 | 
				
			||||||
 | 
					                case BLE_HS_ADV_TYPE_RANDOM_TGT_ADDR:
 | 
				
			||||||
 | 
					                    count += field->length / 6;
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                default:
 | 
				
			||||||
 | 
					                    count++;
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if(data_loc != nullptr) {
 | 
				
			||||||
 | 
					                if(index == 0 || count >= index) {
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        length -= 1 + field->length;
 | 
				
			||||||
 | 
					        data += 1 + field->length;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(data_loc != nullptr && field != nullptr) {
 | 
				
			||||||
 | 
					        *data_loc = data;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return count;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set the address of the advertised device.
 | 
				
			||||||
 | 
					 * @param [in] address The address of the advertised device.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEAdvertisedDevice::setAddress(NimBLEAddress address) {
 | 
				
			||||||
 | 
					    m_address = address;
 | 
				
			||||||
 | 
					} // setAddress
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set the adFlag for this device.
 | 
				
			||||||
 | 
					 * @param [in] advType The advertisement flag data from the advertisement.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEAdvertisedDevice::setAdvType(uint8_t advType) {
 | 
				
			||||||
 | 
					    m_advType = advType;
 | 
				
			||||||
 | 
					} // setAdvType
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set the RSSI for this device.
 | 
				
			||||||
 | 
					 * @param [in] rssi The RSSI of the discovered device.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEAdvertisedDevice::setRSSI(int rssi) {
 | 
				
			||||||
 | 
					    m_rssi = rssi;
 | 
				
			||||||
 | 
					} // setRSSI
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Create a string representation of this device.
 | 
				
			||||||
 | 
					 * @return A string representation of this device.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					std::string NimBLEAdvertisedDevice::toString() {
 | 
				
			||||||
 | 
					    std::string res = "Name: " + getName() + ", Address: " + getAddress().toString();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (haveAppearance()) {
 | 
				
			||||||
 | 
					        char val[6];
 | 
				
			||||||
 | 
					        snprintf(val, sizeof(val), "%d", getAppearance());
 | 
				
			||||||
 | 
					        res += ", appearance: ";
 | 
				
			||||||
 | 
					        res += val;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (haveManufacturerData()) {
 | 
				
			||||||
 | 
					        char *pHex = NimBLEUtils::buildHexData(nullptr, (uint8_t*)getManufacturerData().data(), getManufacturerData().length());
 | 
				
			||||||
 | 
					        res += ", manufacturer data: ";
 | 
				
			||||||
 | 
					        res += pHex;
 | 
				
			||||||
 | 
					        free(pHex);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (haveServiceUUID()) {
 | 
				
			||||||
 | 
					        res += ", serviceUUID: " + getServiceUUID().toString();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (haveTXPower()) {
 | 
				
			||||||
 | 
					        char val[5];
 | 
				
			||||||
 | 
					        snprintf(val, sizeof(val), "%d", getTXPower());
 | 
				
			||||||
 | 
					        res += ", txPower: ";
 | 
				
			||||||
 | 
					        res += val;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(haveServiceData()) {
 | 
				
			||||||
 | 
					        size_t count = getServiceDataCount();
 | 
				
			||||||
 | 
					        res += "\nService Data:";
 | 
				
			||||||
 | 
					        for(size_t i = 0; i < count; i++) {
 | 
				
			||||||
 | 
					            res += "\nUUID: " + std::string(getServiceDataUUID(i));
 | 
				
			||||||
 | 
					            res += ", Data: " + getServiceData(i);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // toString
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the payload advertised by the device.
 | 
				
			||||||
 | 
					 * @return The advertisement payload.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint8_t* NimBLEAdvertisedDevice::getPayload() {
 | 
				
			||||||
 | 
					    return &m_payload[0];
 | 
				
			||||||
 | 
					} // getPayload
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Stores the payload of the advertised device in a vector.
 | 
				
			||||||
 | 
					 * @param [in] payload The advertisement payload.
 | 
				
			||||||
 | 
					 * @param [in] length The length of the payload in bytes.
 | 
				
			||||||
 | 
					 * @param [in] append Indicates if the the data should be appended (scan response).
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEAdvertisedDevice::setPayload(const uint8_t *payload, uint8_t length, bool append) {
 | 
				
			||||||
 | 
					    if(!append) {
 | 
				
			||||||
 | 
					        m_advLength = length;
 | 
				
			||||||
 | 
					        m_payload.assign(payload, payload + length);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        m_payload.insert(m_payload.end(), payload, payload + length);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the length of the advertisement data in the payload.
 | 
				
			||||||
 | 
					 * @return The number of bytes in the payload that is from the advertisment.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint8_t NimBLEAdvertisedDevice::getAdvLength() {
 | 
				
			||||||
 | 
					    return m_advLength;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the advertised device address type.
 | 
				
			||||||
 | 
					 * @return The device address type:
 | 
				
			||||||
 | 
					 * * BLE_ADDR_PUBLIC      (0x00)
 | 
				
			||||||
 | 
					 * * BLE_ADDR_RANDOM      (0x01)
 | 
				
			||||||
 | 
					 * * BLE_ADDR_PUBLIC_ID   (0x02)
 | 
				
			||||||
 | 
					 * * BLE_ADDR_RANDOM_ID   (0x03)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint8_t NimBLEAdvertisedDevice::getAddressType() {
 | 
				
			||||||
 | 
					    return m_address.getType();
 | 
				
			||||||
 | 
					} // getAddressType
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the timeStamp of when the device last advertised.
 | 
				
			||||||
 | 
					 * @return The timeStamp of when the device was last seen.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					time_t NimBLEAdvertisedDevice::getTimestamp() {
 | 
				
			||||||
 | 
					    return m_timestamp;
 | 
				
			||||||
 | 
					} // getTimestamp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the length of the payload advertised by the device.
 | 
				
			||||||
 | 
					 * @return The size of the payload in bytes.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					size_t NimBLEAdvertisedDevice::getPayloadLength() {
 | 
				
			||||||
 | 
					    return m_payload.size();
 | 
				
			||||||
 | 
					} // getPayloadLength
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* CONFIG_BT_ENABLED  && CONFIG_BT_NIMBLE_ROLE_CENTRAL */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										177
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEAdvertisedDevice.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										177
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEAdvertisedDevice.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,177 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * NimBLEAdvertisedDevice.h
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created: on Jan 24 2020
 | 
				
			||||||
 | 
					 *      Author H2zero
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Originally:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * BLEAdvertisedDevice.h
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created on: Jul 3, 2017
 | 
				
			||||||
 | 
					 *      Author: kolban
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef COMPONENTS_NIMBLEADVERTISEDDEVICE_H_
 | 
				
			||||||
 | 
					#define COMPONENTS_NIMBLEADVERTISEDDEVICE_H_
 | 
				
			||||||
 | 
					#include "nimconfig.h"
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "NimBLEAddress.h"
 | 
				
			||||||
 | 
					#include "NimBLEScan.h"
 | 
				
			||||||
 | 
					#include "NimBLEUUID.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(CONFIG_NIMBLE_CPP_IDF)
 | 
				
			||||||
 | 
					#include "host/ble_hs_adv.h"
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#include "nimble/nimble/host/include/host/ble_hs_adv.h"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <map>
 | 
				
			||||||
 | 
					#include <vector>
 | 
				
			||||||
 | 
					#include <time.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class NimBLEScan;
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief A representation of a %BLE advertised device found by a scan.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * When we perform a %BLE scan, the result will be a set of devices that are advertising.  This
 | 
				
			||||||
 | 
					 * class provides a model of a detected device.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class NimBLEAdvertisedDevice {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    NimBLEAdvertisedDevice();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NimBLEAddress   getAddress();
 | 
				
			||||||
 | 
					    uint8_t         getAdvType();
 | 
				
			||||||
 | 
					    uint16_t        getAppearance();
 | 
				
			||||||
 | 
					    uint16_t        getAdvInterval();
 | 
				
			||||||
 | 
					    uint16_t        getMinInterval();
 | 
				
			||||||
 | 
					    uint16_t        getMaxInterval();
 | 
				
			||||||
 | 
					    std::string     getManufacturerData();
 | 
				
			||||||
 | 
					    std::string     getURI();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief A template to convert the service data to <type\>.
 | 
				
			||||||
 | 
					     * @tparam T The type to convert the data to.
 | 
				
			||||||
 | 
					     * @param [in] skipSizeCheck If true it will skip checking if the data size is less than <tt>sizeof(<type\>)</tt>.
 | 
				
			||||||
 | 
					     * @return The data converted to <type\> or NULL if skipSizeCheck is false and the data is
 | 
				
			||||||
 | 
					     * less than <tt>sizeof(<type\>)</tt>.
 | 
				
			||||||
 | 
					     * @details <b>Use:</b> <tt>getManufacturerData<type>(skipSizeCheck);</tt>
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    template<typename T>
 | 
				
			||||||
 | 
					    T       getManufacturerData(bool skipSizeCheck = false) {
 | 
				
			||||||
 | 
					        std::string data = getManufacturerData();
 | 
				
			||||||
 | 
					        if(!skipSizeCheck && data.size() < sizeof(T)) return T();
 | 
				
			||||||
 | 
					        const char *pData = data.data();
 | 
				
			||||||
 | 
					        return *((T *)pData);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::string     getName();
 | 
				
			||||||
 | 
					    int             getRSSI();
 | 
				
			||||||
 | 
					    NimBLEScan*     getScan();
 | 
				
			||||||
 | 
					    size_t          getServiceDataCount();
 | 
				
			||||||
 | 
					    std::string     getServiceData(uint8_t index = 0);
 | 
				
			||||||
 | 
					    std::string     getServiceData(const NimBLEUUID &uuid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief A template to convert the service data to <tt><type\></tt>.
 | 
				
			||||||
 | 
					     * @tparam T The type to convert the data to.
 | 
				
			||||||
 | 
					     * @param [in] index The vector index of the service data requested.
 | 
				
			||||||
 | 
					     * @param [in] skipSizeCheck If true it will skip checking if the data size is less than <tt>sizeof(<type\>)</tt>.
 | 
				
			||||||
 | 
					     * @return The data converted to <type\> or NULL if skipSizeCheck is false and the data is
 | 
				
			||||||
 | 
					     * less than <tt>sizeof(<type\>)</tt>.
 | 
				
			||||||
 | 
					     * @details <b>Use:</b> <tt>getServiceData<type>(skipSizeCheck);</tt>
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    template<typename T>
 | 
				
			||||||
 | 
					    T       getServiceData(uint8_t index = 0, bool skipSizeCheck = false) {
 | 
				
			||||||
 | 
					        std::string data = getServiceData(index);
 | 
				
			||||||
 | 
					        if(!skipSizeCheck && data.size() < sizeof(T)) return T();
 | 
				
			||||||
 | 
					        const char *pData = data.data();
 | 
				
			||||||
 | 
					        return *((T *)pData);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief A template to convert the service data to <tt><type\></tt>.
 | 
				
			||||||
 | 
					     * @tparam T The type to convert the data to.
 | 
				
			||||||
 | 
					     * @param [in] uuid The uuid of the service data requested.
 | 
				
			||||||
 | 
					     * @param [in] skipSizeCheck If true it will skip checking if the data size is less than <tt>sizeof(<type\>)</tt>.
 | 
				
			||||||
 | 
					     * @return The data converted to <type\> or NULL if skipSizeCheck is false and the data is
 | 
				
			||||||
 | 
					     * less than <tt>sizeof(<type\>)</tt>.
 | 
				
			||||||
 | 
					     * @details <b>Use:</b> <tt>getServiceData<type>(skipSizeCheck);</tt>
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    template<typename T>
 | 
				
			||||||
 | 
					    T       getServiceData(const NimBLEUUID &uuid, bool skipSizeCheck = false) {
 | 
				
			||||||
 | 
					        std::string data = getServiceData(uuid);
 | 
				
			||||||
 | 
					        if(!skipSizeCheck && data.size() < sizeof(T)) return T();
 | 
				
			||||||
 | 
					        const char *pData = data.data();
 | 
				
			||||||
 | 
					        return *((T *)pData);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NimBLEUUID      getServiceDataUUID(uint8_t index = 0);
 | 
				
			||||||
 | 
					    NimBLEUUID      getServiceUUID(uint8_t index = 0);
 | 
				
			||||||
 | 
					    size_t          getServiceUUIDCount();
 | 
				
			||||||
 | 
					    NimBLEAddress   getTargetAddress(uint8_t index = 0);
 | 
				
			||||||
 | 
					    size_t          getTargetAddressCount();
 | 
				
			||||||
 | 
					    int8_t          getTXPower();
 | 
				
			||||||
 | 
					    uint8_t*        getPayload();
 | 
				
			||||||
 | 
					    uint8_t         getAdvLength();
 | 
				
			||||||
 | 
					    size_t          getPayloadLength();
 | 
				
			||||||
 | 
					    uint8_t         getAddressType();
 | 
				
			||||||
 | 
					    time_t          getTimestamp();
 | 
				
			||||||
 | 
					    bool            isAdvertisingService(const NimBLEUUID &uuid);
 | 
				
			||||||
 | 
					    bool            haveAppearance();
 | 
				
			||||||
 | 
					    bool            haveManufacturerData();
 | 
				
			||||||
 | 
					    bool            haveName();
 | 
				
			||||||
 | 
					    bool            haveRSSI();
 | 
				
			||||||
 | 
					    bool            haveServiceData();
 | 
				
			||||||
 | 
					    bool            haveServiceUUID();
 | 
				
			||||||
 | 
					    bool            haveTXPower();
 | 
				
			||||||
 | 
					    bool            haveConnParams();
 | 
				
			||||||
 | 
					    bool            haveAdvInterval();
 | 
				
			||||||
 | 
					    bool            haveTargetAddress();
 | 
				
			||||||
 | 
					    bool            haveURI();
 | 
				
			||||||
 | 
					    std::string     toString();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    friend class NimBLEScan;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void    setAddress(NimBLEAddress address);
 | 
				
			||||||
 | 
					    void    setAdvType(uint8_t advType);
 | 
				
			||||||
 | 
					    void    setPayload(const uint8_t *payload, uint8_t length, bool append);
 | 
				
			||||||
 | 
					    void    setRSSI(int rssi);
 | 
				
			||||||
 | 
					    uint8_t findAdvField(uint8_t type, uint8_t index = 0, uint8_t *data_loc = nullptr);
 | 
				
			||||||
 | 
					    uint8_t findServiceData(uint8_t index, uint8_t* bytes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NimBLEAddress   m_address = NimBLEAddress("");
 | 
				
			||||||
 | 
					    uint8_t         m_advType;
 | 
				
			||||||
 | 
					    int             m_rssi;
 | 
				
			||||||
 | 
					    time_t          m_timestamp;
 | 
				
			||||||
 | 
					    bool            m_callbackSent;
 | 
				
			||||||
 | 
					    uint8_t         m_advLength;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::vector<uint8_t>    m_payload;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief A callback handler for callbacks associated device scanning.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * When we are performing a scan as a %BLE client, we may wish to know when a new device that is advertising
 | 
				
			||||||
 | 
					 * has been found.  This class can be sub-classed and registered such that when a scan is performed and
 | 
				
			||||||
 | 
					 * a new advertised device has been found, we will be called back to be notified.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class NimBLEAdvertisedDeviceCallbacks {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    virtual ~NimBLEAdvertisedDeviceCallbacks() {}
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Called when a new scan result is detected.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * As we are scanning, we will find new devices.  When found, this call back is invoked with a reference to the
 | 
				
			||||||
 | 
					     * device that was found.  During any individual scan, a device will only be detected one time.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual void onResult(NimBLEAdvertisedDevice* advertisedDevice) = 0;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_OBSERVER */
 | 
				
			||||||
 | 
					#endif /* COMPONENTS_NIMBLEADVERTISEDDEVICE_H_ */
 | 
				
			||||||
							
								
								
									
										1029
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEAdvertising.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1029
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEAdvertising.cpp
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										138
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEAdvertising.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEAdvertising.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,138 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * NimBLEAdvertising.h
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created: on March 3, 2020
 | 
				
			||||||
 | 
					 *      Author H2zero
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Originally:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * BLEAdvertising.h
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created on: Jun 21, 2017
 | 
				
			||||||
 | 
					 *      Author: kolban
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef MAIN_BLEADVERTISING_H_
 | 
				
			||||||
 | 
					#define MAIN_BLEADVERTISING_H_
 | 
				
			||||||
 | 
					#include "nimconfig.h"
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(CONFIG_NIMBLE_CPP_IDF)
 | 
				
			||||||
 | 
					#include "host/ble_gap.h"
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#include "nimble/nimble/host/include/host/ble_gap.h"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/****  FIX COMPILATION ****/
 | 
				
			||||||
 | 
					#undef min
 | 
				
			||||||
 | 
					#undef max
 | 
				
			||||||
 | 
					/**************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "NimBLEUUID.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <vector>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* COMPATIBILITY - DO NOT USE */
 | 
				
			||||||
 | 
					#define ESP_BLE_ADV_FLAG_LIMIT_DISC         (0x01 << 0)
 | 
				
			||||||
 | 
					#define ESP_BLE_ADV_FLAG_GEN_DISC           (0x01 << 1)
 | 
				
			||||||
 | 
					#define ESP_BLE_ADV_FLAG_BREDR_NOT_SPT      (0x01 << 2)
 | 
				
			||||||
 | 
					#define ESP_BLE_ADV_FLAG_DMT_CONTROLLER_SPT (0x01 << 3)
 | 
				
			||||||
 | 
					#define ESP_BLE_ADV_FLAG_DMT_HOST_SPT       (0x01 << 4)
 | 
				
			||||||
 | 
					#define ESP_BLE_ADV_FLAG_NON_LIMIT_DISC     (0x00 )
 | 
				
			||||||
 | 
					 /* ************************* */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Advertisement data set by the programmer to be published by the %BLE server.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class NimBLEAdvertisementData {
 | 
				
			||||||
 | 
					    // Only a subset of the possible BLE architected advertisement fields are currently exposed.  Others will
 | 
				
			||||||
 | 
					    // be exposed on demand/request or as time permits.
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    void setAppearance(uint16_t appearance);
 | 
				
			||||||
 | 
					    void setCompleteServices(const NimBLEUUID &uuid);
 | 
				
			||||||
 | 
					    void setCompleteServices16(const std::vector<NimBLEUUID> &v_uuid);
 | 
				
			||||||
 | 
					    void setCompleteServices32(const std::vector<NimBLEUUID> &v_uuid);
 | 
				
			||||||
 | 
					    void setFlags(uint8_t);
 | 
				
			||||||
 | 
					    void setManufacturerData(const std::string &data);
 | 
				
			||||||
 | 
					    void setURI(const std::string &uri);
 | 
				
			||||||
 | 
					    void setName(const std::string &name);
 | 
				
			||||||
 | 
					    void setPartialServices(const NimBLEUUID &uuid);
 | 
				
			||||||
 | 
					    void setPartialServices16(const std::vector<NimBLEUUID> &v_uuid);
 | 
				
			||||||
 | 
					    void setPartialServices32(const std::vector<NimBLEUUID> &v_uuid);
 | 
				
			||||||
 | 
					    void setServiceData(const NimBLEUUID &uuid, const std::string &data);
 | 
				
			||||||
 | 
					    void setShortName(const std::string &name);
 | 
				
			||||||
 | 
					    void addData(const std::string &data);  // Add data to the payload.
 | 
				
			||||||
 | 
					    void addData(char * data, size_t length);
 | 
				
			||||||
 | 
					    void addTxPower();
 | 
				
			||||||
 | 
					    void setPreferredParams(uint16_t min, uint16_t max);
 | 
				
			||||||
 | 
					    std::string getPayload();               // Retrieve the current advert payload.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    friend class NimBLEAdvertising;
 | 
				
			||||||
 | 
					    void setServices(const bool complete, const uint8_t size,
 | 
				
			||||||
 | 
					                     const std::vector<NimBLEUUID> &v_uuid);
 | 
				
			||||||
 | 
					    std::string m_payload;   // The payload of the advertisement.
 | 
				
			||||||
 | 
					};   // NimBLEAdvertisementData
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Perform and manage %BLE advertising.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * A %BLE server will want to perform advertising in order to make itself known to %BLE clients.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class NimBLEAdvertising {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    NimBLEAdvertising();
 | 
				
			||||||
 | 
					    void addServiceUUID(const NimBLEUUID &serviceUUID);
 | 
				
			||||||
 | 
					    void addServiceUUID(const char* serviceUUID);
 | 
				
			||||||
 | 
					    void removeServiceUUID(const NimBLEUUID &serviceUUID);
 | 
				
			||||||
 | 
					    bool start(uint32_t duration = 0, void (*advCompleteCB)(NimBLEAdvertising *pAdv) = nullptr);
 | 
				
			||||||
 | 
					    void stop();
 | 
				
			||||||
 | 
					    void setAppearance(uint16_t appearance);
 | 
				
			||||||
 | 
					    void setName(const std::string &name);
 | 
				
			||||||
 | 
					    void setManufacturerData(const std::string &data);
 | 
				
			||||||
 | 
					    void setURI(const std::string &uri);
 | 
				
			||||||
 | 
					    void setServiceData(const NimBLEUUID &uuid, const std::string &data);
 | 
				
			||||||
 | 
					    void setAdvertisementType(uint8_t adv_type);
 | 
				
			||||||
 | 
					    void setMaxInterval(uint16_t maxinterval);
 | 
				
			||||||
 | 
					    void setMinInterval(uint16_t mininterval);
 | 
				
			||||||
 | 
					    void setAdvertisementData(NimBLEAdvertisementData& advertisementData);
 | 
				
			||||||
 | 
					    void setScanFilter(bool scanRequestWhitelistOnly, bool connectWhitelistOnly);
 | 
				
			||||||
 | 
					    void setScanResponseData(NimBLEAdvertisementData& advertisementData);
 | 
				
			||||||
 | 
					    void setScanResponse(bool);
 | 
				
			||||||
 | 
					    void setMinPreferred(uint16_t);
 | 
				
			||||||
 | 
					    void setMaxPreferred(uint16_t);
 | 
				
			||||||
 | 
					    void addTxPower();
 | 
				
			||||||
 | 
					    void reset();
 | 
				
			||||||
 | 
					    void advCompleteCB();
 | 
				
			||||||
 | 
					    bool isAdvertising();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    friend class NimBLEDevice;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void                    onHostSync();
 | 
				
			||||||
 | 
					    static int              handleGapEvent(struct ble_gap_event *event, void *arg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ble_hs_adv_fields       m_advData;
 | 
				
			||||||
 | 
					    ble_hs_adv_fields       m_scanData;
 | 
				
			||||||
 | 
					    ble_gap_adv_params      m_advParams;
 | 
				
			||||||
 | 
					    std::vector<NimBLEUUID> m_serviceUUIDs;
 | 
				
			||||||
 | 
					    bool                    m_customAdvData;
 | 
				
			||||||
 | 
					    bool                    m_customScanResponseData;
 | 
				
			||||||
 | 
					    bool                    m_scanResp;
 | 
				
			||||||
 | 
					    bool                    m_advDataSet;
 | 
				
			||||||
 | 
					    void                    (*m_advCompCB)(NimBLEAdvertising *pAdv);
 | 
				
			||||||
 | 
					    uint8_t                 m_slaveItvl[4];
 | 
				
			||||||
 | 
					    uint32_t                m_duration;
 | 
				
			||||||
 | 
					    std::vector<uint8_t>    m_svcData16;
 | 
				
			||||||
 | 
					    std::vector<uint8_t>    m_svcData32;
 | 
				
			||||||
 | 
					    std::vector<uint8_t>    m_svcData128;
 | 
				
			||||||
 | 
					    std::vector<uint8_t>    m_name;
 | 
				
			||||||
 | 
					    std::vector<uint8_t>    m_mfgData;
 | 
				
			||||||
 | 
					    std::vector<uint8_t>    m_uri;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_BROADCASTER */
 | 
				
			||||||
 | 
					#endif /* MAIN_BLEADVERTISING_H_ */
 | 
				
			||||||
							
								
								
									
										157
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEBeacon.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEBeacon.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,157 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * NimBLEBeacon2.cpp
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created: on March 15 2020
 | 
				
			||||||
 | 
					 *      Author H2zero
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Originally:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * BLEBeacon.cpp
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created on: Jan 4, 2018
 | 
				
			||||||
 | 
					 *      Author: kolban
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#include "nimconfig.h"
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_ENABLED)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <algorithm>
 | 
				
			||||||
 | 
					#include "NimBLEBeacon.h"
 | 
				
			||||||
 | 
					#include "NimBLELog.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ENDIAN_CHANGE_U16(x) ((((x)&0xFF00)>>8) + (((x)&0xFF)<<8))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char* LOG_TAG = "NimBLEBeacon";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Construct a default beacon object.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEBeacon::NimBLEBeacon() {
 | 
				
			||||||
 | 
					    m_beaconData.manufacturerId = 0x4c00;
 | 
				
			||||||
 | 
					    m_beaconData.subType        = 0x02;
 | 
				
			||||||
 | 
					    m_beaconData.subTypeLength  = 0x15;
 | 
				
			||||||
 | 
					    m_beaconData.major          = 0;
 | 
				
			||||||
 | 
					    m_beaconData.minor          = 0;
 | 
				
			||||||
 | 
					    m_beaconData.signalPower    = 0;
 | 
				
			||||||
 | 
					    memset(m_beaconData.proximityUUID, 0, sizeof(m_beaconData.proximityUUID));
 | 
				
			||||||
 | 
					} // NimBLEBeacon
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Retrieve the data that is being advertised.
 | 
				
			||||||
 | 
					 * @return The advertised data.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					std::string NimBLEBeacon::getData() {
 | 
				
			||||||
 | 
					    return std::string((char*) &m_beaconData, sizeof(m_beaconData));
 | 
				
			||||||
 | 
					} // getData
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the major value being advertised.
 | 
				
			||||||
 | 
					 * @return The major value advertised.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint16_t NimBLEBeacon::getMajor() {
 | 
				
			||||||
 | 
					    return m_beaconData.major;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the manufacturer ID being advertised.
 | 
				
			||||||
 | 
					 * @return The manufacturer ID value advertised.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint16_t NimBLEBeacon::getManufacturerId() {
 | 
				
			||||||
 | 
					    return m_beaconData.manufacturerId;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the minor value being advertised.
 | 
				
			||||||
 | 
					 * @return minor value advertised.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint16_t NimBLEBeacon::getMinor() {
 | 
				
			||||||
 | 
					    return m_beaconData.minor;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the proximity UUID being advertised.
 | 
				
			||||||
 | 
					 * @return The UUID advertised.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEUUID NimBLEBeacon::getProximityUUID() {
 | 
				
			||||||
 | 
					    return NimBLEUUID(m_beaconData.proximityUUID, 16, true);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the signal power being advertised.
 | 
				
			||||||
 | 
					 * @return signal power level advertised.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int8_t NimBLEBeacon::getSignalPower() {
 | 
				
			||||||
 | 
					    return m_beaconData.signalPower;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set the raw data for the beacon record.
 | 
				
			||||||
 | 
					 * @param [in] data The raw beacon data.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEBeacon::setData(const std::string &data) {
 | 
				
			||||||
 | 
					    if (data.length() != sizeof(m_beaconData)) {
 | 
				
			||||||
 | 
					        NIMBLE_LOGE(LOG_TAG, "Unable to set the data ... length passed in was %d and expected %d",
 | 
				
			||||||
 | 
					                                                        data.length(), sizeof(m_beaconData));
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    memcpy(&m_beaconData, data.data(), sizeof(m_beaconData));
 | 
				
			||||||
 | 
					} // setData
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set the major value.
 | 
				
			||||||
 | 
					 * @param [in] major The major value.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEBeacon::setMajor(uint16_t major) {
 | 
				
			||||||
 | 
					    m_beaconData.major = ENDIAN_CHANGE_U16(major);
 | 
				
			||||||
 | 
					} // setMajor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set the manufacturer ID.
 | 
				
			||||||
 | 
					 * @param [in] manufacturerId The manufacturer ID value.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEBeacon::setManufacturerId(uint16_t manufacturerId) {
 | 
				
			||||||
 | 
					    m_beaconData.manufacturerId = ENDIAN_CHANGE_U16(manufacturerId);
 | 
				
			||||||
 | 
					} // setManufacturerId
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set the minor value.
 | 
				
			||||||
 | 
					 * @param [in] minor The minor value.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEBeacon::setMinor(uint16_t minor) {
 | 
				
			||||||
 | 
					    m_beaconData.minor = ENDIAN_CHANGE_U16(minor);
 | 
				
			||||||
 | 
					} // setMinior
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set the proximity UUID.
 | 
				
			||||||
 | 
					 * @param [in] uuid The proximity UUID.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEBeacon::setProximityUUID(const NimBLEUUID &uuid) {
 | 
				
			||||||
 | 
					    NimBLEUUID temp_uuid = uuid;
 | 
				
			||||||
 | 
					    temp_uuid.to128();
 | 
				
			||||||
 | 
					    std::reverse_copy(temp_uuid.getNative()->u128.value,
 | 
				
			||||||
 | 
					                      temp_uuid.getNative()->u128.value + 16,
 | 
				
			||||||
 | 
					                      m_beaconData.proximityUUID);
 | 
				
			||||||
 | 
					} // setProximityUUID
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set the signal power.
 | 
				
			||||||
 | 
					 * @param [in] signalPower The signal power value.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEBeacon::setSignalPower(int8_t signalPower) {
 | 
				
			||||||
 | 
					    m_beaconData.signalPower = signalPower;
 | 
				
			||||||
 | 
					} // setSignalPower
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										51
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEBeacon.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEBeacon.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * NimBLEBeacon2.h
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created: on March 15 2020
 | 
				
			||||||
 | 
					 *      Author H2zero
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Originally:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * BLEBeacon2.h
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created on: Jan 4, 2018
 | 
				
			||||||
 | 
					 *      Author: kolban
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef MAIN_NIMBLEBEACON_H_
 | 
				
			||||||
 | 
					#define MAIN_NIMBLEBEACON_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "NimBLEUUID.h"
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Representation of a beacon.
 | 
				
			||||||
 | 
					 * See:
 | 
				
			||||||
 | 
					 * * https://en.wikipedia.org/wiki/IBeacon
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class NimBLEBeacon {
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    struct {
 | 
				
			||||||
 | 
					        uint16_t manufacturerId;
 | 
				
			||||||
 | 
					        uint8_t  subType;
 | 
				
			||||||
 | 
					        uint8_t  subTypeLength;
 | 
				
			||||||
 | 
					        uint8_t  proximityUUID[16];
 | 
				
			||||||
 | 
					        uint16_t major;
 | 
				
			||||||
 | 
					        uint16_t minor;
 | 
				
			||||||
 | 
					        int8_t   signalPower;
 | 
				
			||||||
 | 
					    } __attribute__((packed)) m_beaconData;
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    NimBLEBeacon();
 | 
				
			||||||
 | 
					    std::string getData();
 | 
				
			||||||
 | 
					    uint16_t    getMajor();
 | 
				
			||||||
 | 
					    uint16_t    getMinor();
 | 
				
			||||||
 | 
					    uint16_t    getManufacturerId();
 | 
				
			||||||
 | 
					    NimBLEUUID     getProximityUUID();
 | 
				
			||||||
 | 
					    int8_t      getSignalPower();
 | 
				
			||||||
 | 
					    void        setData(const std::string &data);
 | 
				
			||||||
 | 
					    void        setMajor(uint16_t major);
 | 
				
			||||||
 | 
					    void        setMinor(uint16_t minor);
 | 
				
			||||||
 | 
					    void        setManufacturerId(uint16_t manufacturerId);
 | 
				
			||||||
 | 
					    void        setProximityUUID(const NimBLEUUID &uuid);
 | 
				
			||||||
 | 
					    void        setSignalPower(int8_t signalPower);
 | 
				
			||||||
 | 
					}; // NimBLEBeacon
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* MAIN_NIMBLEBEACON_H_ */
 | 
				
			||||||
							
								
								
									
										649
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLECharacteristic.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										649
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLECharacteristic.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,649 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * NimBLECharacteristic.cpp
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created: on March 3, 2020
 | 
				
			||||||
 | 
					 *      Author H2zero
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * BLECharacteristic.cpp
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created on: Jun 22, 2017
 | 
				
			||||||
 | 
					 *      Author: kolban
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "nimconfig.h"
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "NimBLECharacteristic.h"
 | 
				
			||||||
 | 
					#include "NimBLE2904.h"
 | 
				
			||||||
 | 
					#include "NimBLEDevice.h"
 | 
				
			||||||
 | 
					#include "NimBLELog.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define NULL_HANDLE (0xffff)
 | 
				
			||||||
 | 
					#define NIMBLE_SUB_NOTIFY   0x0001
 | 
				
			||||||
 | 
					#define NIMBLE_SUB_INDICATE 0x0002
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static NimBLECharacteristicCallbacks defaultCallback;
 | 
				
			||||||
 | 
					static const char* LOG_TAG = "NimBLECharacteristic";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Construct a characteristic
 | 
				
			||||||
 | 
					 * @param [in] uuid - UUID (const char*) for the characteristic.
 | 
				
			||||||
 | 
					 * @param [in] properties - Properties for the characteristic.
 | 
				
			||||||
 | 
					 * @param [in] pService - pointer to the service instance this characteristic belongs to.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLECharacteristic::NimBLECharacteristic(const char* uuid, uint16_t properties, NimBLEService* pService)
 | 
				
			||||||
 | 
					: NimBLECharacteristic(NimBLEUUID(uuid), properties, pService) {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Construct a characteristic
 | 
				
			||||||
 | 
					 * @param [in] uuid - UUID for the characteristic.
 | 
				
			||||||
 | 
					 * @param [in] properties - Properties for the characteristic.
 | 
				
			||||||
 | 
					 * @param [in] pService - pointer to the service instance this characteristic belongs to.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLECharacteristic::NimBLECharacteristic(const NimBLEUUID &uuid, uint16_t properties, NimBLEService* pService) {
 | 
				
			||||||
 | 
					    m_uuid        = uuid;
 | 
				
			||||||
 | 
					    m_handle      = NULL_HANDLE;
 | 
				
			||||||
 | 
					    m_properties  = properties;
 | 
				
			||||||
 | 
					    m_pCallbacks  = &defaultCallback;
 | 
				
			||||||
 | 
					    m_pService    = pService;
 | 
				
			||||||
 | 
					    m_value       = "";
 | 
				
			||||||
 | 
					    m_timestamp   = 0;
 | 
				
			||||||
 | 
					    m_removed     = 0;
 | 
				
			||||||
 | 
					} // NimBLECharacteristic
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Destructor.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLECharacteristic::~NimBLECharacteristic() {
 | 
				
			||||||
 | 
					    for(auto &it : m_dscVec) {
 | 
				
			||||||
 | 
					        delete it;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					} // ~NimBLECharacteristic
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Create a new BLE Descriptor associated with this characteristic.
 | 
				
			||||||
 | 
					 * @param [in] uuid - The UUID of the descriptor.
 | 
				
			||||||
 | 
					 * @param [in] properties - The properties of the descriptor.
 | 
				
			||||||
 | 
					 * @param [in] max_len - The max length in bytes of the descriptor value.
 | 
				
			||||||
 | 
					 * @return The new BLE descriptor.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEDescriptor* NimBLECharacteristic::createDescriptor(const char* uuid, uint32_t properties, uint16_t max_len) {
 | 
				
			||||||
 | 
					    return createDescriptor(NimBLEUUID(uuid), properties, max_len);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Create a new BLE Descriptor associated with this characteristic.
 | 
				
			||||||
 | 
					 * @param [in] uuid - The UUID of the descriptor.
 | 
				
			||||||
 | 
					 * @param [in] properties - The properties of the descriptor.
 | 
				
			||||||
 | 
					 * @param [in] max_len - The max length in bytes of the descriptor value.
 | 
				
			||||||
 | 
					 * @return The new BLE descriptor.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEDescriptor* NimBLECharacteristic::createDescriptor(const NimBLEUUID &uuid, uint32_t properties, uint16_t max_len) {
 | 
				
			||||||
 | 
					    NimBLEDescriptor* pDescriptor = nullptr;
 | 
				
			||||||
 | 
					    if(uuid == NimBLEUUID(uint16_t(0x2902))) {
 | 
				
			||||||
 | 
					        assert(0 && "0x2902 descriptors cannot be manually created");
 | 
				
			||||||
 | 
					    } else if (uuid == NimBLEUUID(uint16_t(0x2904))) {
 | 
				
			||||||
 | 
					        pDescriptor = new NimBLE2904(this);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        pDescriptor = new NimBLEDescriptor(uuid, properties, max_len, this);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    addDescriptor(pDescriptor);
 | 
				
			||||||
 | 
					    return pDescriptor;
 | 
				
			||||||
 | 
					} // createDescriptor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Add a descriptor to the characteristic.
 | 
				
			||||||
 | 
					 * @param [in] pDescriptor A pointer to the descriptor to add.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLECharacteristic::addDescriptor(NimBLEDescriptor *pDescriptor) {
 | 
				
			||||||
 | 
					    bool foundRemoved = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(pDescriptor->m_removed > 0) {
 | 
				
			||||||
 | 
					        for(auto& it : m_dscVec) {
 | 
				
			||||||
 | 
					            if(it == pDescriptor) {
 | 
				
			||||||
 | 
					                foundRemoved = true;
 | 
				
			||||||
 | 
					                pDescriptor->m_removed = 0;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(!foundRemoved) {
 | 
				
			||||||
 | 
					        m_dscVec.push_back(pDescriptor);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pDescriptor->setCharacteristic(this);
 | 
				
			||||||
 | 
					    NimBLEDevice::getServer()->serviceChanged();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Remove a descriptor from the characterisitc.
 | 
				
			||||||
 | 
					 * @param[in] pDescriptor A pointer to the descriptor instance to remove from the characterisitc.
 | 
				
			||||||
 | 
					 * @param[in] deleteDsc If true it will delete the descriptor instance and free it's resources.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLECharacteristic::removeDescriptor(NimBLEDescriptor *pDescriptor, bool deleteDsc) {
 | 
				
			||||||
 | 
					    // Check if the descriptor was already removed and if so, check if this
 | 
				
			||||||
 | 
					    // is being called to delete the object and do so if requested.
 | 
				
			||||||
 | 
					    // Otherwise, ignore the call and return.
 | 
				
			||||||
 | 
					    if(pDescriptor->m_removed > 0) {
 | 
				
			||||||
 | 
					        if(deleteDsc) {
 | 
				
			||||||
 | 
					            for(auto it = m_dscVec.begin(); it != m_dscVec.end(); ++it) {
 | 
				
			||||||
 | 
					                if ((*it) == pDescriptor) {
 | 
				
			||||||
 | 
					                    delete *it;
 | 
				
			||||||
 | 
					                    m_dscVec.erase(it);
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pDescriptor->m_removed = deleteDsc ? NIMBLE_ATT_REMOVE_DELETE : NIMBLE_ATT_REMOVE_HIDE;
 | 
				
			||||||
 | 
					    NimBLEDevice::getServer()->serviceChanged();
 | 
				
			||||||
 | 
					} // removeDescriptor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Return the BLE Descriptor for the given UUID.
 | 
				
			||||||
 | 
					 * @param [in] uuid The UUID of the descriptor.
 | 
				
			||||||
 | 
					 * @return A pointer to the descriptor object or nullptr if not found.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEDescriptor* NimBLECharacteristic::getDescriptorByUUID(const char* uuid) {
 | 
				
			||||||
 | 
					    return getDescriptorByUUID(NimBLEUUID(uuid));
 | 
				
			||||||
 | 
					} // getDescriptorByUUID
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Return the BLE Descriptor for the given UUID.
 | 
				
			||||||
 | 
					 * @param [in] uuid The UUID of the descriptor.
 | 
				
			||||||
 | 
					 * @return A pointer to the descriptor object or nullptr if not found.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEDescriptor* NimBLECharacteristic::getDescriptorByUUID(const NimBLEUUID &uuid) {
 | 
				
			||||||
 | 
					    for (auto &it : m_dscVec) {
 | 
				
			||||||
 | 
					        if (it->getUUID() == uuid) {
 | 
				
			||||||
 | 
					            return it;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return nullptr;
 | 
				
			||||||
 | 
					} // getDescriptorByUUID
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Return the BLE Descriptor for the given handle.
 | 
				
			||||||
 | 
					 * @param [in] handle The handle of the descriptor.
 | 
				
			||||||
 | 
					 * @return A pointer to the descriptor object or nullptr if not found.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEDescriptor *NimBLECharacteristic::getDescriptorByHandle(uint16_t handle) {
 | 
				
			||||||
 | 
					    for (auto &it : m_dscVec) {
 | 
				
			||||||
 | 
					        if (it->getHandle() == handle) {
 | 
				
			||||||
 | 
					            return it;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return nullptr;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the handle of the characteristic.
 | 
				
			||||||
 | 
					 * @return The handle of the characteristic.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint16_t NimBLECharacteristic::getHandle() {
 | 
				
			||||||
 | 
					    return m_handle;
 | 
				
			||||||
 | 
					} // getHandle
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the properties of the characteristic.
 | 
				
			||||||
 | 
					 * @return The properties of the characteristic.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint16_t NimBLECharacteristic::getProperties() {
 | 
				
			||||||
 | 
					    return m_properties;
 | 
				
			||||||
 | 
					} // getProperties
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the service associated with this characteristic.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEService* NimBLECharacteristic::getService() {
 | 
				
			||||||
 | 
					    return m_pService;
 | 
				
			||||||
 | 
					} // getService
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void NimBLECharacteristic::setService(NimBLEService *pService) {
 | 
				
			||||||
 | 
					    m_pService = pService;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the UUID of the characteristic.
 | 
				
			||||||
 | 
					 * @return The UUID of the characteristic.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEUUID NimBLECharacteristic::getUUID() {
 | 
				
			||||||
 | 
					    return m_uuid;
 | 
				
			||||||
 | 
					} // getUUID
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Retrieve the current value of the characteristic.
 | 
				
			||||||
 | 
					 * @return A std::string containing the current characteristic value.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					std::string NimBLECharacteristic::getValue(time_t *timestamp) {
 | 
				
			||||||
 | 
					    ble_npl_hw_enter_critical();
 | 
				
			||||||
 | 
					    std::string retVal = m_value;
 | 
				
			||||||
 | 
					    if(timestamp != nullptr) {
 | 
				
			||||||
 | 
					        *timestamp = m_timestamp;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    ble_npl_hw_exit_critical(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return retVal;
 | 
				
			||||||
 | 
					} // getValue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Retrieve the the current data length of the characteristic.
 | 
				
			||||||
 | 
					 * @return The length of the current characteristic data.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					size_t NimBLECharacteristic::getDataLength() {
 | 
				
			||||||
 | 
					    ble_npl_hw_enter_critical();
 | 
				
			||||||
 | 
					    size_t len = m_value.length();
 | 
				
			||||||
 | 
					    ble_npl_hw_exit_critical(0);
 | 
				
			||||||
 | 
					    return len;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief STATIC callback to handle events from the NimBLE stack.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int NimBLECharacteristic::handleGapEvent(uint16_t conn_handle, uint16_t attr_handle,
 | 
				
			||||||
 | 
					                             struct ble_gatt_access_ctxt *ctxt,
 | 
				
			||||||
 | 
					                             void *arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    const ble_uuid_t *uuid;
 | 
				
			||||||
 | 
					    int rc;
 | 
				
			||||||
 | 
					    struct ble_gap_conn_desc desc;
 | 
				
			||||||
 | 
					    NimBLECharacteristic* pCharacteristic = (NimBLECharacteristic*)arg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, "Characteristic %s %s event", pCharacteristic->getUUID().toString().c_str(),
 | 
				
			||||||
 | 
					                                    ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR ? "Read" : "Write");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uuid = ctxt->chr->uuid;
 | 
				
			||||||
 | 
					    if(ble_uuid_cmp(uuid, &pCharacteristic->getUUID().getNative()->u) == 0){
 | 
				
			||||||
 | 
					        switch(ctxt->op) {
 | 
				
			||||||
 | 
					            case BLE_GATT_ACCESS_OP_READ_CHR: {
 | 
				
			||||||
 | 
					                // If the packet header is only 8 bytes this is a follow up of a long read
 | 
				
			||||||
 | 
					                // so we don't want to call the onRead() callback again.
 | 
				
			||||||
 | 
					                if(ctxt->om->om_pkthdr_len > 8) {
 | 
				
			||||||
 | 
					                    rc = ble_gap_conn_find(conn_handle, &desc);
 | 
				
			||||||
 | 
					                    assert(rc == 0);
 | 
				
			||||||
 | 
					                    pCharacteristic->m_pCallbacks->onRead(pCharacteristic);
 | 
				
			||||||
 | 
					                    pCharacteristic->m_pCallbacks->onRead(pCharacteristic, &desc);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                ble_npl_hw_enter_critical();
 | 
				
			||||||
 | 
					                rc = os_mbuf_append(ctxt->om, (uint8_t*)pCharacteristic->m_value.data(),
 | 
				
			||||||
 | 
					                                    pCharacteristic->m_value.length());
 | 
				
			||||||
 | 
					                ble_npl_hw_exit_critical(0);
 | 
				
			||||||
 | 
					                return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            case BLE_GATT_ACCESS_OP_WRITE_CHR: {
 | 
				
			||||||
 | 
					                if (ctxt->om->om_len > BLE_ATT_ATTR_MAX_LEN) {
 | 
				
			||||||
 | 
					                    return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                uint8_t buf[BLE_ATT_ATTR_MAX_LEN];
 | 
				
			||||||
 | 
					                size_t len = ctxt->om->om_len;
 | 
				
			||||||
 | 
					                memcpy(buf, ctxt->om->om_data,len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                os_mbuf *next;
 | 
				
			||||||
 | 
					                next = SLIST_NEXT(ctxt->om, om_next);
 | 
				
			||||||
 | 
					                while(next != NULL){
 | 
				
			||||||
 | 
					                    if((len + next->om_len) > BLE_ATT_ATTR_MAX_LEN) {
 | 
				
			||||||
 | 
					                        return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    memcpy(&buf[len], next->om_data, next->om_len);
 | 
				
			||||||
 | 
					                    len += next->om_len;
 | 
				
			||||||
 | 
					                    next = SLIST_NEXT(next, om_next);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                rc = ble_gap_conn_find(conn_handle, &desc);
 | 
				
			||||||
 | 
					                assert(rc == 0);
 | 
				
			||||||
 | 
					                pCharacteristic->setValue(buf, len);
 | 
				
			||||||
 | 
					                pCharacteristic->m_pCallbacks->onWrite(pCharacteristic);
 | 
				
			||||||
 | 
					                pCharacteristic->m_pCallbacks->onWrite(pCharacteristic, &desc);
 | 
				
			||||||
 | 
					                return 0;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            default:
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return BLE_ATT_ERR_UNLIKELY;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the number of clients subscribed to the characteristic.
 | 
				
			||||||
 | 
					 * @returns Number of clients subscribed to notifications / indications.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					size_t NimBLECharacteristic::getSubscribedCount() {
 | 
				
			||||||
 | 
					    return m_subscribedVec.size();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set the subscribe status for this characteristic.\n
 | 
				
			||||||
 | 
					 * This will maintain a vector of subscribed clients and their indicate/notify status.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLECharacteristic::setSubscribe(struct ble_gap_event *event) {
 | 
				
			||||||
 | 
					    ble_gap_conn_desc desc;
 | 
				
			||||||
 | 
					    if(ble_gap_conn_find(event->subscribe.conn_handle, &desc) != 0) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint16_t subVal = 0;
 | 
				
			||||||
 | 
					    if(event->subscribe.cur_notify > 0 && (m_properties & NIMBLE_PROPERTY::NOTIFY)) {
 | 
				
			||||||
 | 
					        subVal |= NIMBLE_SUB_NOTIFY;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if(event->subscribe.cur_indicate && (m_properties & NIMBLE_PROPERTY::INDICATE)) {
 | 
				
			||||||
 | 
					        subVal |= NIMBLE_SUB_INDICATE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NIMBLE_LOGI(LOG_TAG, "New subscribe value for conn: %d val: %d",
 | 
				
			||||||
 | 
					                          event->subscribe.conn_handle, subVal);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(!event->subscribe.cur_indicate && event->subscribe.prev_indicate) {
 | 
				
			||||||
 | 
					       NimBLEDevice::getServer()->clearIndicateWait(event->subscribe.conn_handle);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    auto it = m_subscribedVec.begin();
 | 
				
			||||||
 | 
					    for(;it != m_subscribedVec.end(); ++it) {
 | 
				
			||||||
 | 
					        if((*it).first == event->subscribe.conn_handle) {
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(subVal > 0) {
 | 
				
			||||||
 | 
					        if(it == m_subscribedVec.end()) {
 | 
				
			||||||
 | 
					            m_subscribedVec.push_back({event->subscribe.conn_handle, subVal});
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            (*it).second = subVal;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    } else if(it != m_subscribedVec.end()) {
 | 
				
			||||||
 | 
					        m_subscribedVec.erase(it);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    m_pCallbacks->onSubscribe(this, &desc, subVal);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Send an indication.\n
 | 
				
			||||||
 | 
					 * An indication is a transmission of up to the first 20 bytes of the characteristic value.\n
 | 
				
			||||||
 | 
					 * An indication will block waiting for a positive confirmation from the client.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLECharacteristic::indicate() {
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, ">> indicate: length: %d", getDataLength());
 | 
				
			||||||
 | 
					    notify(false);
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, "<< indicate");
 | 
				
			||||||
 | 
					} // indicate
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Send a notification.\n
 | 
				
			||||||
 | 
					 * A notification is a transmission of up to the first 20 bytes of the characteristic value.\n
 | 
				
			||||||
 | 
					 * A notification will not block; it is a fire and forget.
 | 
				
			||||||
 | 
					 * @param[in] is_notification if true sends a notification, false sends an indication.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLECharacteristic::notify(bool is_notification) {
 | 
				
			||||||
 | 
					    notify(getValue(), is_notification);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Send a notification.\n
 | 
				
			||||||
 | 
					 * A notification is a transmission of up to the first 20 bytes of the characteristic value.\n
 | 
				
			||||||
 | 
					 * A notification will not block; it is a fire and forget.
 | 
				
			||||||
 | 
					 * @param[in] value An optional value to send as the notification, else the current characteristic value is used.
 | 
				
			||||||
 | 
					 * @param[in] is_notification if true sends a notification, false sends an indication.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLECharacteristic::notify(std::string value, bool is_notification) {
 | 
				
			||||||
 | 
					    size_t length = value.length();
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, ">> notify: length: %d", length);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(!(m_properties & NIMBLE_PROPERTY::NOTIFY) &&
 | 
				
			||||||
 | 
					       !(m_properties & NIMBLE_PROPERTY::INDICATE))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        NIMBLE_LOGE(LOG_TAG,
 | 
				
			||||||
 | 
					                    "<< notify-Error; Notify/indicate not enabled for characterisitc: %s",
 | 
				
			||||||
 | 
					                    std::string(getUUID()).c_str());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (m_subscribedVec.size() == 0) {
 | 
				
			||||||
 | 
					        NIMBLE_LOGD(LOG_TAG, "<< notify: No clients subscribed.");
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    m_pCallbacks->onNotify(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool reqSec = (m_properties & BLE_GATT_CHR_F_READ_AUTHEN) ||
 | 
				
			||||||
 | 
					                  (m_properties & BLE_GATT_CHR_F_READ_AUTHOR) ||
 | 
				
			||||||
 | 
					                  (m_properties & BLE_GATT_CHR_F_READ_ENC);
 | 
				
			||||||
 | 
					    int rc = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (auto &it : m_subscribedVec) {
 | 
				
			||||||
 | 
					        uint16_t _mtu = getService()->getServer()->getPeerMTU(it.first) - 3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // check if connected and subscribed
 | 
				
			||||||
 | 
					        if(_mtu == 0 || it.second == 0) {
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // check if security requirements are satisfied
 | 
				
			||||||
 | 
					        if(reqSec) {
 | 
				
			||||||
 | 
					            struct ble_gap_conn_desc desc;
 | 
				
			||||||
 | 
					            rc = ble_gap_conn_find(it.first, &desc);
 | 
				
			||||||
 | 
					            if(rc != 0 || !desc.sec_state.encrypted) {
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (length > _mtu) {
 | 
				
			||||||
 | 
					            NIMBLE_LOGW(LOG_TAG, "- Truncating to %d bytes (maximum notify size)", _mtu);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(is_notification && (!(it.second & NIMBLE_SUB_NOTIFY))) {
 | 
				
			||||||
 | 
					            NIMBLE_LOGW(LOG_TAG,
 | 
				
			||||||
 | 
					            "Sending notification to client subscribed to indications, sending indication instead");
 | 
				
			||||||
 | 
					            is_notification = false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(!is_notification && (!(it.second & NIMBLE_SUB_INDICATE))) {
 | 
				
			||||||
 | 
					            NIMBLE_LOGW(LOG_TAG,
 | 
				
			||||||
 | 
					            "Sending indication to client subscribed to notification, sending notification instead");
 | 
				
			||||||
 | 
					            is_notification = true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // don't create the m_buf until we are sure to send the data or else
 | 
				
			||||||
 | 
					        // we could be allocating a buffer that doesn't get released.
 | 
				
			||||||
 | 
					        // We also must create it in each loop iteration because it is consumed with each host call.
 | 
				
			||||||
 | 
					        os_mbuf *om = ble_hs_mbuf_from_flat((uint8_t*)value.data(), length);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(!is_notification && (m_properties & NIMBLE_PROPERTY::INDICATE)) {
 | 
				
			||||||
 | 
					            if(!NimBLEDevice::getServer()->setIndicateWait(it.first)) {
 | 
				
			||||||
 | 
					               NIMBLE_LOGE(LOG_TAG, "prior Indication in progress");
 | 
				
			||||||
 | 
					               os_mbuf_free_chain(om);
 | 
				
			||||||
 | 
					               return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            rc = ble_gattc_indicate_custom(it.first, m_handle, om);
 | 
				
			||||||
 | 
					            if(rc != 0){
 | 
				
			||||||
 | 
					                NimBLEDevice::getServer()->clearIndicateWait(it.first);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            ble_gattc_notify_custom(it.first, m_handle, om);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, "<< notify");
 | 
				
			||||||
 | 
					} // Notify
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set the callback handlers for this characteristic.
 | 
				
			||||||
 | 
					 * @param [in] pCallbacks An instance of a NimBLECharacteristicCallbacks class\n
 | 
				
			||||||
 | 
					 * used to define any callbacks for the characteristic.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLECharacteristic::setCallbacks(NimBLECharacteristicCallbacks* pCallbacks) {
 | 
				
			||||||
 | 
					    if (pCallbacks != nullptr){
 | 
				
			||||||
 | 
					        m_pCallbacks = pCallbacks;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        m_pCallbacks = &defaultCallback;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					} // setCallbacks
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the callback handlers for this characteristic.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLECharacteristicCallbacks* NimBLECharacteristic::getCallbacks() {
 | 
				
			||||||
 | 
					    return m_pCallbacks;
 | 
				
			||||||
 | 
					} //getCallbacks
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set the value of the characteristic.
 | 
				
			||||||
 | 
					 * @param [in] data The data to set for the characteristic.
 | 
				
			||||||
 | 
					 * @param [in] length The length of the data in bytes.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLECharacteristic::setValue(const uint8_t* data, size_t length) {
 | 
				
			||||||
 | 
					#if CONFIG_NIMBLE_CPP_LOG_LEVEL >= 4
 | 
				
			||||||
 | 
					    char* pHex = NimBLEUtils::buildHexData(nullptr, data, length);
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, ">> setValue: length=%d, data=%s, characteristic UUID=%s", length, pHex, getUUID().toString().c_str());
 | 
				
			||||||
 | 
					    free(pHex);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (length > BLE_ATT_ATTR_MAX_LEN) {
 | 
				
			||||||
 | 
					        NIMBLE_LOGE(LOG_TAG, "Size %d too large, must be no bigger than %d", length, BLE_ATT_ATTR_MAX_LEN);
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    time_t t = time(nullptr);
 | 
				
			||||||
 | 
					    ble_npl_hw_enter_critical();
 | 
				
			||||||
 | 
					    m_value = std::string((char*)data, length);
 | 
				
			||||||
 | 
					    m_timestamp = t;
 | 
				
			||||||
 | 
					    ble_npl_hw_exit_critical(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, "<< setValue");
 | 
				
			||||||
 | 
					} // setValue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set the value of the characteristic from string data.\n
 | 
				
			||||||
 | 
					 * We set the value of the characteristic from the bytes contained in the string.
 | 
				
			||||||
 | 
					 * @param [in] value the std::string value of the characteristic.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLECharacteristic::setValue(const std::string &value) {
 | 
				
			||||||
 | 
					    setValue((uint8_t*)(value.data()), value.length());
 | 
				
			||||||
 | 
					} // setValue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Return a string representation of the characteristic.
 | 
				
			||||||
 | 
					 * @return A string representation of the characteristic.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					std::string NimBLECharacteristic::toString() {
 | 
				
			||||||
 | 
					    std::string res = "UUID: " + m_uuid.toString() + ", handle : 0x";
 | 
				
			||||||
 | 
					    char hex[5];
 | 
				
			||||||
 | 
					    snprintf(hex, sizeof(hex), "%04x", m_handle);
 | 
				
			||||||
 | 
					    res += hex;
 | 
				
			||||||
 | 
					    res += " ";
 | 
				
			||||||
 | 
					    if (m_properties & BLE_GATT_CHR_PROP_READ ) res += "Read ";
 | 
				
			||||||
 | 
					    if (m_properties & BLE_GATT_CHR_PROP_WRITE) res += "Write ";
 | 
				
			||||||
 | 
					    if (m_properties & BLE_GATT_CHR_PROP_WRITE_NO_RSP) res += "WriteNoResponse ";
 | 
				
			||||||
 | 
					    if (m_properties & BLE_GATT_CHR_PROP_BROADCAST) res += "Broadcast ";
 | 
				
			||||||
 | 
					    if (m_properties & BLE_GATT_CHR_PROP_NOTIFY) res += "Notify ";
 | 
				
			||||||
 | 
					    if (m_properties & BLE_GATT_CHR_PROP_INDICATE) res += "Indicate ";
 | 
				
			||||||
 | 
					    return res;
 | 
				
			||||||
 | 
					} // toString
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NimBLECharacteristicCallbacks::~NimBLECharacteristicCallbacks() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Callback function to support a read request.
 | 
				
			||||||
 | 
					 * @param [in] pCharacteristic The characteristic that is the source of the event.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLECharacteristicCallbacks::onRead(NimBLECharacteristic* pCharacteristic) {
 | 
				
			||||||
 | 
					    NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onRead: default");
 | 
				
			||||||
 | 
					} // onRead
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Callback function to support a read request.
 | 
				
			||||||
 | 
					 * @param [in] pCharacteristic The characteristic that is the source of the event.
 | 
				
			||||||
 | 
					 * @param [in] desc The connection description struct that is associated with the peer that performed the read.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLECharacteristicCallbacks::onRead(NimBLECharacteristic* pCharacteristic, ble_gap_conn_desc* desc) {
 | 
				
			||||||
 | 
					    NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onRead: default");
 | 
				
			||||||
 | 
					} // onRead
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Callback function to support a write request.
 | 
				
			||||||
 | 
					 * @param [in] pCharacteristic The characteristic that is the source of the event.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLECharacteristicCallbacks::onWrite(NimBLECharacteristic* pCharacteristic) {
 | 
				
			||||||
 | 
					    NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onWrite: default");
 | 
				
			||||||
 | 
					} // onWrite
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Callback function to support a write request.
 | 
				
			||||||
 | 
					 * @param [in] pCharacteristic The characteristic that is the source of the event.
 | 
				
			||||||
 | 
					 * @param [in] desc The connection description struct that is associated with the peer that performed the write.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLECharacteristicCallbacks::onWrite(NimBLECharacteristic* pCharacteristic, ble_gap_conn_desc* desc) {
 | 
				
			||||||
 | 
					    NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onWrite: default");
 | 
				
			||||||
 | 
					} // onWrite
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Callback function to support a Notify request.
 | 
				
			||||||
 | 
					 * @param [in] pCharacteristic The characteristic that is the source of the event.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLECharacteristicCallbacks::onNotify(NimBLECharacteristic* pCharacteristic) {
 | 
				
			||||||
 | 
					    NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onNotify: default");
 | 
				
			||||||
 | 
					} // onNotify
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Callback function to support a Notify/Indicate Status report.
 | 
				
			||||||
 | 
					 * @param [in] pCharacteristic The characteristic that is the source of the event.
 | 
				
			||||||
 | 
					 * @param [in] s Status of the notification/indication.
 | 
				
			||||||
 | 
					 * @param [in] code Additional return code from the NimBLE stack.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLECharacteristicCallbacks::onStatus(NimBLECharacteristic* pCharacteristic, Status s, int code) {
 | 
				
			||||||
 | 
					    NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onStatus: default");
 | 
				
			||||||
 | 
					} // onStatus
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Callback function called when a client changes subscription status.
 | 
				
			||||||
 | 
					 * @param [in] pCharacteristic The characteristic that is the source of the event.
 | 
				
			||||||
 | 
					 * @param [in] desc The connection description struct that is associated with the client.
 | 
				
			||||||
 | 
					 * @param [in] subValue The subscription status:
 | 
				
			||||||
 | 
					 * * 0 = Un-Subscribed
 | 
				
			||||||
 | 
					 * * 1 = Notifications
 | 
				
			||||||
 | 
					 * * 2 = Indications
 | 
				
			||||||
 | 
					 * * 3 = Notifications and Indications
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLECharacteristicCallbacks::onSubscribe(NimBLECharacteristic* pCharacteristic,
 | 
				
			||||||
 | 
					                                                ble_gap_conn_desc* desc,
 | 
				
			||||||
 | 
					                                                uint16_t subValue)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onSubscribe: default");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_PERIPHERAL */
 | 
				
			||||||
							
								
								
									
										202
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLECharacteristic.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										202
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLECharacteristic.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,202 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * NimBLECharacteristic.h
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created: on March 3, 2020
 | 
				
			||||||
 | 
					 *      Author H2zero
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Originally:
 | 
				
			||||||
 | 
					 * BLECharacteristic.h
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created on: Jun 22, 2017
 | 
				
			||||||
 | 
					 *      Author: kolban
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef MAIN_NIMBLECHARACTERISTIC_H_
 | 
				
			||||||
 | 
					#define MAIN_NIMBLECHARACTERISTIC_H_
 | 
				
			||||||
 | 
					#include "nimconfig.h"
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(CONFIG_NIMBLE_CPP_IDF)
 | 
				
			||||||
 | 
					#include "host/ble_hs.h"
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#include "nimble/nimble/host/include/host/ble_hs.h"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/****  FIX COMPILATION ****/
 | 
				
			||||||
 | 
					#undef min
 | 
				
			||||||
 | 
					#undef max
 | 
				
			||||||
 | 
					/**************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
					    READ         =  BLE_GATT_CHR_F_READ,
 | 
				
			||||||
 | 
					    READ_ENC     =  BLE_GATT_CHR_F_READ_ENC,
 | 
				
			||||||
 | 
					    READ_AUTHEN  =  BLE_GATT_CHR_F_READ_AUTHEN,
 | 
				
			||||||
 | 
					    READ_AUTHOR  =  BLE_GATT_CHR_F_READ_AUTHOR,
 | 
				
			||||||
 | 
					    WRITE        =  BLE_GATT_CHR_F_WRITE,
 | 
				
			||||||
 | 
					    WRITE_NR     =  BLE_GATT_CHR_F_WRITE_NO_RSP,
 | 
				
			||||||
 | 
					    WRITE_ENC    =  BLE_GATT_CHR_F_WRITE_ENC,
 | 
				
			||||||
 | 
					    WRITE_AUTHEN =  BLE_GATT_CHR_F_WRITE_AUTHEN,
 | 
				
			||||||
 | 
					    WRITE_AUTHOR =  BLE_GATT_CHR_F_WRITE_AUTHOR,
 | 
				
			||||||
 | 
					    BROADCAST    =  BLE_GATT_CHR_F_BROADCAST,
 | 
				
			||||||
 | 
					    NOTIFY       =  BLE_GATT_CHR_F_NOTIFY,
 | 
				
			||||||
 | 
					    INDICATE     =  BLE_GATT_CHR_F_INDICATE
 | 
				
			||||||
 | 
					} NIMBLE_PROPERTY;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "NimBLEService.h"
 | 
				
			||||||
 | 
					#include "NimBLEDescriptor.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					#include <vector>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class NimBLEService;
 | 
				
			||||||
 | 
					class NimBLEDescriptor;
 | 
				
			||||||
 | 
					class NimBLECharacteristicCallbacks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief The model of a %BLE Characteristic.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * A BLE Characteristic is an identified value container that manages a value. It is exposed by a BLE server and
 | 
				
			||||||
 | 
					 * can be read and written to by a %BLE client.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class NimBLECharacteristic {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    NimBLECharacteristic(const char* uuid,
 | 
				
			||||||
 | 
					                         uint16_t properties =
 | 
				
			||||||
 | 
					                         NIMBLE_PROPERTY::READ |
 | 
				
			||||||
 | 
					                         NIMBLE_PROPERTY::WRITE,
 | 
				
			||||||
 | 
					                         NimBLEService* pService = nullptr);
 | 
				
			||||||
 | 
					    NimBLECharacteristic(const NimBLEUUID &uuid,
 | 
				
			||||||
 | 
					                         uint16_t properties =
 | 
				
			||||||
 | 
					                         NIMBLE_PROPERTY::READ |
 | 
				
			||||||
 | 
					                         NIMBLE_PROPERTY::WRITE,
 | 
				
			||||||
 | 
					                         NimBLEService* pService = nullptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ~NimBLECharacteristic();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint16_t          getHandle();
 | 
				
			||||||
 | 
					    NimBLEUUID        getUUID();
 | 
				
			||||||
 | 
					    std::string       toString();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void              setCallbacks(NimBLECharacteristicCallbacks* pCallbacks);
 | 
				
			||||||
 | 
					    NimBLECharacteristicCallbacks*
 | 
				
			||||||
 | 
					                      getCallbacks();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void              indicate();
 | 
				
			||||||
 | 
					    void              notify(bool is_notification = true);
 | 
				
			||||||
 | 
					    void              notify(std::string value, bool is_notification = true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    size_t            getSubscribedCount();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NimBLEDescriptor* createDescriptor(const char* uuid,
 | 
				
			||||||
 | 
					                                       uint32_t properties =
 | 
				
			||||||
 | 
					                                       NIMBLE_PROPERTY::READ |
 | 
				
			||||||
 | 
					                                       NIMBLE_PROPERTY::WRITE,
 | 
				
			||||||
 | 
					                                       uint16_t max_len = 100);
 | 
				
			||||||
 | 
					    NimBLEDescriptor* createDescriptor(const NimBLEUUID &uuid,
 | 
				
			||||||
 | 
					                                       uint32_t properties =
 | 
				
			||||||
 | 
					                                       NIMBLE_PROPERTY::READ |
 | 
				
			||||||
 | 
					                                       NIMBLE_PROPERTY::WRITE,
 | 
				
			||||||
 | 
					                                       uint16_t max_len = 100);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void              addDescriptor(NimBLEDescriptor *pDescriptor);
 | 
				
			||||||
 | 
					    NimBLEDescriptor* getDescriptorByUUID(const char* uuid);
 | 
				
			||||||
 | 
					    NimBLEDescriptor* getDescriptorByUUID(const NimBLEUUID &uuid);
 | 
				
			||||||
 | 
					    NimBLEDescriptor* getDescriptorByHandle(uint16_t handle);
 | 
				
			||||||
 | 
					    void              removeDescriptor(NimBLEDescriptor *pDescriptor, bool deleteDsc = false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::string       getValue(time_t *timestamp = nullptr);
 | 
				
			||||||
 | 
					    size_t            getDataLength();
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief A template to convert the characteristic data to <type\>.
 | 
				
			||||||
 | 
					     * @tparam T The type to convert the data to.
 | 
				
			||||||
 | 
					     * @param [in] timestamp A pointer to a time_t struct to store the time the value was read.
 | 
				
			||||||
 | 
					     * @param [in] skipSizeCheck If true it will skip checking if the data size is less than <tt>sizeof(<type\>)</tt>.
 | 
				
			||||||
 | 
					     * @return The data converted to <type\> or NULL if skipSizeCheck is false and the data is
 | 
				
			||||||
 | 
					     * less than <tt>sizeof(<type\>)</tt>.
 | 
				
			||||||
 | 
					     * @details <b>Use:</b> <tt>getValue<type>(×tamp, skipSizeCheck);</tt>
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    template<typename T>
 | 
				
			||||||
 | 
					    T                 getValue(time_t *timestamp = nullptr, bool skipSizeCheck = false) {
 | 
				
			||||||
 | 
					        std::string value = getValue();
 | 
				
			||||||
 | 
					        if(!skipSizeCheck && value.size() < sizeof(T)) return T();
 | 
				
			||||||
 | 
					        const char *pData = value.data();
 | 
				
			||||||
 | 
					        return *((T *)pData);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void              setValue(const uint8_t* data, size_t size);
 | 
				
			||||||
 | 
					    void              setValue(const std::string &value);
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Convenience template to set the characteristic value to <type\>val.
 | 
				
			||||||
 | 
					     * @param [in] s The value to set.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    template<typename T>
 | 
				
			||||||
 | 
					    void              setValue(const T &s) {
 | 
				
			||||||
 | 
					        setValue((uint8_t*)&s, sizeof(T));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NimBLEService*    getService();
 | 
				
			||||||
 | 
					    uint16_t          getProperties();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    friend class    NimBLEServer;
 | 
				
			||||||
 | 
					    friend class    NimBLEService;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void            setService(NimBLEService *pService);
 | 
				
			||||||
 | 
					    void            setSubscribe(struct ble_gap_event *event);
 | 
				
			||||||
 | 
					    static int      handleGapEvent(uint16_t conn_handle, uint16_t attr_handle,
 | 
				
			||||||
 | 
					                                   struct ble_gatt_access_ctxt *ctxt, void *arg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NimBLEUUID                     m_uuid;
 | 
				
			||||||
 | 
					    uint16_t                       m_handle;
 | 
				
			||||||
 | 
					    uint16_t                       m_properties;
 | 
				
			||||||
 | 
					    NimBLECharacteristicCallbacks* m_pCallbacks;
 | 
				
			||||||
 | 
					    NimBLEService*                 m_pService;
 | 
				
			||||||
 | 
					    std::string                    m_value;
 | 
				
			||||||
 | 
					    std::vector<NimBLEDescriptor*> m_dscVec;
 | 
				
			||||||
 | 
					    time_t                         m_timestamp;
 | 
				
			||||||
 | 
					    uint8_t                        m_removed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::vector<std::pair<uint16_t, uint16_t>>  m_subscribedVec;
 | 
				
			||||||
 | 
					}; // NimBLECharacteristic
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Callbacks that can be associated with a %BLE characteristic to inform of events.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * When a server application creates a %BLE characteristic, we may wish to be informed when there is either
 | 
				
			||||||
 | 
					 * a read or write request to the characteristic's value. An application can register a
 | 
				
			||||||
 | 
					 * sub-classed instance of this class and will be notified when such an event happens.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class NimBLECharacteristicCallbacks {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief An enum to provide the callback the status of the
 | 
				
			||||||
 | 
					 * notification/indication, implemented for backward compatibility.
 | 
				
			||||||
 | 
					 * @deprecated To be removed in the future as the NimBLE stack return code is also provided.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					    typedef enum {
 | 
				
			||||||
 | 
					        SUCCESS_INDICATE,
 | 
				
			||||||
 | 
					        SUCCESS_NOTIFY,
 | 
				
			||||||
 | 
					        ERROR_INDICATE_DISABLED,
 | 
				
			||||||
 | 
					        ERROR_NOTIFY_DISABLED,
 | 
				
			||||||
 | 
					        ERROR_GATT,
 | 
				
			||||||
 | 
					        ERROR_NO_CLIENT,
 | 
				
			||||||
 | 
					        ERROR_INDICATE_TIMEOUT,
 | 
				
			||||||
 | 
					        ERROR_INDICATE_FAILURE
 | 
				
			||||||
 | 
					    }Status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    virtual ~NimBLECharacteristicCallbacks();
 | 
				
			||||||
 | 
					    virtual void onRead(NimBLECharacteristic* pCharacteristic);
 | 
				
			||||||
 | 
					    virtual void onRead(NimBLECharacteristic* pCharacteristic, ble_gap_conn_desc* desc);
 | 
				
			||||||
 | 
					    virtual void onWrite(NimBLECharacteristic* pCharacteristic);
 | 
				
			||||||
 | 
					    virtual void onWrite(NimBLECharacteristic* pCharacteristic, ble_gap_conn_desc* desc);
 | 
				
			||||||
 | 
					    virtual void onNotify(NimBLECharacteristic* pCharacteristic);
 | 
				
			||||||
 | 
					    virtual void onStatus(NimBLECharacteristic* pCharacteristic, Status s, int code);
 | 
				
			||||||
 | 
					    virtual void onSubscribe(NimBLECharacteristic* pCharacteristic, ble_gap_conn_desc* desc, uint16_t subValue);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* CONFIG_BT_ENABLED  && CONFIG_BT_NIMBLE_ROLE_PERIPHERAL */
 | 
				
			||||||
 | 
					#endif /*MAIN_NIMBLECHARACTERISTIC_H_*/
 | 
				
			||||||
							
								
								
									
										1251
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEClient.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1251
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEClient.cpp
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										162
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEClient.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEClient.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,162 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * NimBLEClient.h
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created: on Jan 26 2020
 | 
				
			||||||
 | 
					 *      Author H2zero
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Originally:
 | 
				
			||||||
 | 
					 * BLEClient.h
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created on: Mar 22, 2017
 | 
				
			||||||
 | 
					 *      Author: kolban
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef MAIN_NIMBLECLIENT_H_
 | 
				
			||||||
 | 
					#define MAIN_NIMBLECLIENT_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "nimconfig.h"
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "NimBLEAddress.h"
 | 
				
			||||||
 | 
					#include "NimBLEUUID.h"
 | 
				
			||||||
 | 
					#include "NimBLEUtils.h"
 | 
				
			||||||
 | 
					#include "NimBLEConnInfo.h"
 | 
				
			||||||
 | 
					#include "NimBLEAdvertisedDevice.h"
 | 
				
			||||||
 | 
					#include "NimBLERemoteService.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <vector>
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class NimBLERemoteService;
 | 
				
			||||||
 | 
					class NimBLERemoteCharacteristic;
 | 
				
			||||||
 | 
					class NimBLEClientCallbacks;
 | 
				
			||||||
 | 
					class NimBLEAdvertisedDevice;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief A model of a %BLE client.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class NimBLEClient {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    bool                                        connect(NimBLEAdvertisedDevice* device, bool deleteAttibutes = true);
 | 
				
			||||||
 | 
					    bool                                        connect(const NimBLEAddress &address, bool deleteAttibutes = true);
 | 
				
			||||||
 | 
					    bool                                        connect(bool deleteAttibutes = true);
 | 
				
			||||||
 | 
					    int                                         disconnect(uint8_t reason = BLE_ERR_REM_USER_CONN_TERM);
 | 
				
			||||||
 | 
					    NimBLEAddress                               getPeerAddress();
 | 
				
			||||||
 | 
					    void                                        setPeerAddress(const NimBLEAddress &address);
 | 
				
			||||||
 | 
					    int                                         getRssi();
 | 
				
			||||||
 | 
					    std::vector<NimBLERemoteService*>*          getServices(bool refresh = false);
 | 
				
			||||||
 | 
					    std::vector<NimBLERemoteService*>::iterator begin();
 | 
				
			||||||
 | 
					    std::vector<NimBLERemoteService*>::iterator end();
 | 
				
			||||||
 | 
					    NimBLERemoteService*                        getService(const char* uuid);
 | 
				
			||||||
 | 
					    NimBLERemoteService*                        getService(const NimBLEUUID &uuid);
 | 
				
			||||||
 | 
					    void                                        deleteServices();
 | 
				
			||||||
 | 
					    size_t                                      deleteService(const NimBLEUUID &uuid);
 | 
				
			||||||
 | 
					    std::string                                 getValue(const NimBLEUUID &serviceUUID, const NimBLEUUID &characteristicUUID);
 | 
				
			||||||
 | 
					    bool                                        setValue(const NimBLEUUID &serviceUUID, const NimBLEUUID &characteristicUUID,
 | 
				
			||||||
 | 
					                                                         const std::string &value, bool response = false);
 | 
				
			||||||
 | 
					    NimBLERemoteCharacteristic*                 getCharacteristic(const uint16_t handle);
 | 
				
			||||||
 | 
					    bool                                        isConnected();
 | 
				
			||||||
 | 
					    void                                        setClientCallbacks(NimBLEClientCallbacks *pClientCallbacks,
 | 
				
			||||||
 | 
					                                                                   bool deleteCallbacks = true);
 | 
				
			||||||
 | 
					    std::string                                 toString();
 | 
				
			||||||
 | 
					    uint16_t                                    getConnId();
 | 
				
			||||||
 | 
					    uint16_t                                    getMTU();
 | 
				
			||||||
 | 
					    bool                                        secureConnection();
 | 
				
			||||||
 | 
					    void                                        setConnectTimeout(uint8_t timeout);
 | 
				
			||||||
 | 
					    void                                        setConnectionParams(uint16_t minInterval, uint16_t maxInterval,
 | 
				
			||||||
 | 
					                                                                    uint16_t latency, uint16_t timeout,
 | 
				
			||||||
 | 
					                                                                    uint16_t scanInterval=16, uint16_t scanWindow=16);
 | 
				
			||||||
 | 
					    void                                        updateConnParams(uint16_t minInterval, uint16_t maxInterval,
 | 
				
			||||||
 | 
					                                                                 uint16_t latency, uint16_t timeout);
 | 
				
			||||||
 | 
					    void                                        setDataLen(uint16_t tx_octets);
 | 
				
			||||||
 | 
					    void                                        discoverAttributes();
 | 
				
			||||||
 | 
					    NimBLEConnInfo                              getConnInfo();
 | 
				
			||||||
 | 
					    int                                         getLastError();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    NimBLEClient(const NimBLEAddress &peerAddress);
 | 
				
			||||||
 | 
					    ~NimBLEClient();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    friend class            NimBLEDevice;
 | 
				
			||||||
 | 
					    friend class            NimBLERemoteService;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static int              handleGapEvent(struct ble_gap_event *event, void *arg);
 | 
				
			||||||
 | 
					    static int              serviceDiscoveredCB(uint16_t conn_handle,
 | 
				
			||||||
 | 
					                                                const struct ble_gatt_error *error,
 | 
				
			||||||
 | 
					                                                const struct ble_gatt_svc *service,
 | 
				
			||||||
 | 
					                                                void *arg);
 | 
				
			||||||
 | 
					    static void             dcTimerCb(ble_npl_event *event);
 | 
				
			||||||
 | 
					    bool                    retrieveServices(const NimBLEUUID *uuid_filter = nullptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NimBLEAddress           m_peerAddress;
 | 
				
			||||||
 | 
					    int                     m_lastErr;
 | 
				
			||||||
 | 
					    uint16_t                m_conn_id;
 | 
				
			||||||
 | 
					    bool                    m_connEstablished;
 | 
				
			||||||
 | 
					    bool                    m_deleteCallbacks;
 | 
				
			||||||
 | 
					    int32_t                 m_connectTimeout;
 | 
				
			||||||
 | 
					    NimBLEClientCallbacks*  m_pClientCallbacks;
 | 
				
			||||||
 | 
					    ble_task_data_t*        m_pTaskData;
 | 
				
			||||||
 | 
					    ble_npl_callout         m_dcTimer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::vector<NimBLERemoteService*> m_servicesVector;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    friend class NimBLEClientCallbacks;
 | 
				
			||||||
 | 
					    ble_gap_conn_params m_pConnParams;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}; // class NimBLEClient
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Callbacks associated with a %BLE client.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class NimBLEClientCallbacks {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    virtual ~NimBLEClientCallbacks() {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Called after client connects.
 | 
				
			||||||
 | 
					     * @param [in] pClient A pointer to the calling client object.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual void onConnect(NimBLEClient* pClient);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Called when disconnected from the server.
 | 
				
			||||||
 | 
					     * @param [in] pClient A pointer to the calling client object.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual void onDisconnect(NimBLEClient* pClient);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Called when server requests to update the connection parameters.
 | 
				
			||||||
 | 
					     * @param [in] pClient A pointer to the calling client object.
 | 
				
			||||||
 | 
					     * @param [in] params A pointer to the struct containing the connection parameters requested.
 | 
				
			||||||
 | 
					     * @return True to accept the parmeters.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual bool onConnParamsUpdateRequest(NimBLEClient* pClient, const ble_gap_upd_params* params);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Called when server requests a passkey for pairing.
 | 
				
			||||||
 | 
					     * @return The passkey to be sent to the server.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual uint32_t onPassKeyRequest();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*virtual void onPassKeyNotify(uint32_t pass_key);
 | 
				
			||||||
 | 
					    virtual bool onSecurityRequest();*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Called when the pairing procedure is complete.
 | 
				
			||||||
 | 
					     * @param [in] desc A pointer to the struct containing the connection information.\n
 | 
				
			||||||
 | 
					     * This can be used to check the status of the connection encryption/pairing.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual void onAuthenticationComplete(ble_gap_conn_desc* desc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Called when using numeric comparision for pairing.
 | 
				
			||||||
 | 
					     * @param [in] pin The pin to compare with the server.
 | 
				
			||||||
 | 
					     * @return True to accept the pin.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual bool onConfirmPIN(uint32_t pin);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_CENTRAL */
 | 
				
			||||||
 | 
					#endif /* MAIN_NIMBLECLIENT_H_ */
 | 
				
			||||||
							
								
								
									
										55
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEConnInfo.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEConnInfo.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,55 @@
 | 
				
			|||||||
 | 
					#ifndef NIMBLECONNINFO_H_
 | 
				
			||||||
 | 
					#define NIMBLECONNINFO_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "NimBLEAddress.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Connection information.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class NimBLEConnInfo {
 | 
				
			||||||
 | 
					friend class NimBLEServer;
 | 
				
			||||||
 | 
					friend class NimBLEClient;
 | 
				
			||||||
 | 
					    ble_gap_conn_desc m_desc;
 | 
				
			||||||
 | 
					    NimBLEConnInfo()                       { m_desc = {}; }
 | 
				
			||||||
 | 
					    NimBLEConnInfo(ble_gap_conn_desc desc) { m_desc = desc; }
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    /** @brief Gets the over-the-air address of the connected peer */
 | 
				
			||||||
 | 
					    NimBLEAddress    getAddress()          { return NimBLEAddress(m_desc.peer_ota_addr); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** @brief Gets the ID address of the connected peer */
 | 
				
			||||||
 | 
					    NimBLEAddress    getIdAddress()        { return NimBLEAddress(m_desc.peer_id_addr); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** @brief Gets the connection handle of the connected peer */
 | 
				
			||||||
 | 
					    uint16_t         getConnHandle()       { return m_desc.conn_handle; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** @brief Gets the connection interval for this connection (in 1.25ms units) */
 | 
				
			||||||
 | 
					    uint16_t         getConnInterval()     { return m_desc.conn_itvl; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** @brief Gets the supervision timeout for this connection (in 10ms units) */
 | 
				
			||||||
 | 
					    uint16_t         getConnTimeout()      { return m_desc.supervision_timeout; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** @brief Gets the allowable latency for this connection (unit = number of intervals) */
 | 
				
			||||||
 | 
					    uint16_t         getConnLatency()      { return m_desc.conn_latency; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** @brief Gets the maximum transmission unit size for this connection (in bytes) */
 | 
				
			||||||
 | 
					    uint16_t         getMTU()              { return ble_att_mtu(m_desc.conn_handle); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** @brief Check if we are in the master role in this connection */
 | 
				
			||||||
 | 
					    bool             isMaster()            { return (m_desc.role == BLE_GAP_ROLE_MASTER); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** @brief Check if we are in the slave role in this connection */
 | 
				
			||||||
 | 
					    bool             isSlave()             { return (m_desc.role == BLE_GAP_ROLE_SLAVE); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** @brief Check if we are connected to a bonded peer */
 | 
				
			||||||
 | 
					    bool             isBonded()            { return (m_desc.sec_state.bonded == 1); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** @brief Check if the connection in encrypted */
 | 
				
			||||||
 | 
					    bool             isEncrypted()         { return (m_desc.sec_state.encrypted == 1); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** @brief Check if the the connection has been authenticated */
 | 
				
			||||||
 | 
					    bool             isAuthenticated()     { return (m_desc.sec_state.authenticated == 1); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** @brief Gets the key size used to encrypt the connection */
 | 
				
			||||||
 | 
					    uint8_t          getSecKeySize()       { return m_desc.sec_state.key_size; }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										297
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEDescriptor.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										297
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEDescriptor.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,297 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * NimBLEDescriptor.cpp
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created: on March 10, 2020
 | 
				
			||||||
 | 
					 *      Author H2zero
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Originally:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * BLEDescriptor.cpp
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created on: Jun 22, 2017
 | 
				
			||||||
 | 
					 *      Author: kolban
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "nimconfig.h"
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "NimBLEService.h"
 | 
				
			||||||
 | 
					#include "NimBLEDescriptor.h"
 | 
				
			||||||
 | 
					#include "NimBLELog.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define NULL_HANDLE (0xffff)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char* LOG_TAG = "NimBLEDescriptor";
 | 
				
			||||||
 | 
					static NimBLEDescriptorCallbacks defaultCallbacks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief NimBLEDescriptor constructor.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEDescriptor::NimBLEDescriptor(const char* uuid, uint16_t properties, uint16_t max_len,
 | 
				
			||||||
 | 
					                                    NimBLECharacteristic* pCharacteristic)
 | 
				
			||||||
 | 
					: NimBLEDescriptor(NimBLEUUID(uuid), max_len, properties, pCharacteristic) {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief NimBLEDescriptor constructor.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEDescriptor::NimBLEDescriptor(NimBLEUUID uuid, uint16_t properties, uint16_t max_len,
 | 
				
			||||||
 | 
					                                    NimBLECharacteristic* pCharacteristic)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    m_uuid               = uuid;
 | 
				
			||||||
 | 
					    m_value.attr_len     = 0;                           // Initial length is 0.
 | 
				
			||||||
 | 
					    m_value.attr_max_len = max_len;                     // Maximum length of the data.
 | 
				
			||||||
 | 
					    m_handle             = NULL_HANDLE;                 // Handle is initially unknown.
 | 
				
			||||||
 | 
					    m_pCharacteristic    = pCharacteristic;
 | 
				
			||||||
 | 
					    m_pCallbacks         = &defaultCallbacks;           // No initial callback.
 | 
				
			||||||
 | 
					    m_value.attr_value   = (uint8_t*) calloc(max_len,1);  // Allocate storage for the value.
 | 
				
			||||||
 | 
					    m_properties         = 0;
 | 
				
			||||||
 | 
					    m_removed            = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (properties & BLE_GATT_CHR_F_READ) {             // convert uint16_t properties to uint8_t
 | 
				
			||||||
 | 
					        m_properties |= BLE_ATT_F_READ;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (properties & (BLE_GATT_CHR_F_WRITE_NO_RSP | BLE_GATT_CHR_F_WRITE)) {
 | 
				
			||||||
 | 
					        m_properties |= BLE_ATT_F_WRITE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (properties & BLE_GATT_CHR_F_READ_ENC) {
 | 
				
			||||||
 | 
					        m_properties |= BLE_ATT_F_READ_ENC;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (properties & BLE_GATT_CHR_F_READ_AUTHEN) {
 | 
				
			||||||
 | 
					        m_properties |= BLE_ATT_F_READ_AUTHEN;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (properties & BLE_GATT_CHR_F_READ_AUTHOR) {
 | 
				
			||||||
 | 
					        m_properties |= BLE_ATT_F_READ_AUTHOR;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (properties & BLE_GATT_CHR_F_WRITE_ENC) {
 | 
				
			||||||
 | 
					        m_properties |= BLE_ATT_F_WRITE_ENC;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (properties & BLE_GATT_CHR_F_WRITE_AUTHEN) {
 | 
				
			||||||
 | 
					        m_properties |= BLE_ATT_F_WRITE_AUTHEN;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (properties & BLE_GATT_CHR_F_WRITE_AUTHOR) {
 | 
				
			||||||
 | 
					        m_properties |= BLE_ATT_F_WRITE_AUTHOR;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // NimBLEDescriptor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief NimBLEDescriptor destructor.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEDescriptor::~NimBLEDescriptor() {
 | 
				
			||||||
 | 
					    free(m_value.attr_value);   // Release the storage we created in the constructor.
 | 
				
			||||||
 | 
					} // ~NimBLEDescriptor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the BLE handle for this descriptor.
 | 
				
			||||||
 | 
					 * @return The handle for this descriptor.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint16_t NimBLEDescriptor::getHandle() {
 | 
				
			||||||
 | 
					    return m_handle;
 | 
				
			||||||
 | 
					} // getHandle
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the length of the value of this descriptor.
 | 
				
			||||||
 | 
					 * @return The length (in bytes) of the value of this descriptor.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					size_t NimBLEDescriptor::getLength() {
 | 
				
			||||||
 | 
					    return m_value.attr_len;
 | 
				
			||||||
 | 
					} // getLength
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the UUID of the descriptor.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEUUID NimBLEDescriptor::getUUID() {
 | 
				
			||||||
 | 
					    return m_uuid;
 | 
				
			||||||
 | 
					} // getUUID
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the value of this descriptor.
 | 
				
			||||||
 | 
					 * @return A pointer to the value of this descriptor.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint8_t* NimBLEDescriptor::getValue() {
 | 
				
			||||||
 | 
					    return m_value.attr_value;
 | 
				
			||||||
 | 
					} // getValue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the value of this descriptor as a string.
 | 
				
			||||||
 | 
					 * @return A std::string instance containing a copy of the descriptor's value.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					std::string NimBLEDescriptor::getStringValue() {
 | 
				
			||||||
 | 
					    return std::string((char *) m_value.attr_value, m_value.attr_len);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the characteristic this descriptor belongs to.
 | 
				
			||||||
 | 
					 * @return A pointer to the characteristic this descriptor belongs to.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLECharacteristic* NimBLEDescriptor::getCharacteristic() {
 | 
				
			||||||
 | 
					    return m_pCharacteristic;
 | 
				
			||||||
 | 
					} // getCharacteristic
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int NimBLEDescriptor::handleGapEvent(uint16_t conn_handle, uint16_t attr_handle,
 | 
				
			||||||
 | 
					                                     struct ble_gatt_access_ctxt *ctxt, void *arg) {
 | 
				
			||||||
 | 
					    (void)conn_handle;
 | 
				
			||||||
 | 
					    (void)attr_handle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const ble_uuid_t *uuid;
 | 
				
			||||||
 | 
					    int rc;
 | 
				
			||||||
 | 
					    NimBLEDescriptor* pDescriptor = (NimBLEDescriptor*)arg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, "Descriptor %s %s event", pDescriptor->getUUID().toString().c_str(),
 | 
				
			||||||
 | 
					                                    ctxt->op == BLE_GATT_ACCESS_OP_READ_DSC ? "Read" : "Write");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uuid = ctxt->chr->uuid;
 | 
				
			||||||
 | 
					    if(ble_uuid_cmp(uuid, &pDescriptor->getUUID().getNative()->u) == 0){
 | 
				
			||||||
 | 
					        switch(ctxt->op) {
 | 
				
			||||||
 | 
					            case BLE_GATT_ACCESS_OP_READ_DSC: {
 | 
				
			||||||
 | 
					                // If the packet header is only 8 bytes this is a follow up of a long read
 | 
				
			||||||
 | 
					                // so we don't want to call the onRead() callback again.
 | 
				
			||||||
 | 
					                if(ctxt->om->om_pkthdr_len > 8) {
 | 
				
			||||||
 | 
					                    pDescriptor->m_pCallbacks->onRead(pDescriptor);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                ble_npl_hw_enter_critical();
 | 
				
			||||||
 | 
					                rc = os_mbuf_append(ctxt->om, pDescriptor->getValue(), pDescriptor->getLength());
 | 
				
			||||||
 | 
					                ble_npl_hw_exit_critical(0);
 | 
				
			||||||
 | 
					                return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            case BLE_GATT_ACCESS_OP_WRITE_DSC: {
 | 
				
			||||||
 | 
					                if (ctxt->om->om_len > pDescriptor->m_value.attr_max_len) {
 | 
				
			||||||
 | 
					                    return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                uint8_t buf[pDescriptor->m_value.attr_max_len];
 | 
				
			||||||
 | 
					                size_t len = ctxt->om->om_len;
 | 
				
			||||||
 | 
					                memcpy(buf, ctxt->om->om_data,len);
 | 
				
			||||||
 | 
					                os_mbuf *next;
 | 
				
			||||||
 | 
					                next = SLIST_NEXT(ctxt->om, om_next);
 | 
				
			||||||
 | 
					                while(next != NULL){
 | 
				
			||||||
 | 
					                    if((len + next->om_len) > pDescriptor->m_value.attr_max_len) {
 | 
				
			||||||
 | 
					                        return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    memcpy(&buf[len], next->om_data, next->om_len);
 | 
				
			||||||
 | 
					                    len += next->om_len;
 | 
				
			||||||
 | 
					                    next = SLIST_NEXT(next, om_next);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                pDescriptor->setValue(buf, len);
 | 
				
			||||||
 | 
					                pDescriptor->m_pCallbacks->onWrite(pDescriptor);
 | 
				
			||||||
 | 
					                return 0;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            default:
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return BLE_ATT_ERR_UNLIKELY;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set the callback handlers for this descriptor.
 | 
				
			||||||
 | 
					 * @param [in] pCallbacks An instance of a callback structure used to define any callbacks for the descriptor.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEDescriptor::setCallbacks(NimBLEDescriptorCallbacks* pCallbacks) {
 | 
				
			||||||
 | 
					    if (pCallbacks != nullptr){
 | 
				
			||||||
 | 
					        m_pCallbacks = pCallbacks;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        m_pCallbacks = &defaultCallbacks;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					} // setCallbacks
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set the handle of this descriptor.
 | 
				
			||||||
 | 
					 * Set the handle of this descriptor to be the supplied value.
 | 
				
			||||||
 | 
					 * @param [in] handle The handle to be associated with this descriptor.
 | 
				
			||||||
 | 
					 * @return N/A.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEDescriptor::setHandle(uint16_t handle) {
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, ">> setHandle(0x%.2x): Setting descriptor handle to be 0x%.2x", handle, handle);
 | 
				
			||||||
 | 
					    m_handle = handle;
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, "<< setHandle()");
 | 
				
			||||||
 | 
					} // setHandle
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set the value of the descriptor.
 | 
				
			||||||
 | 
					 * @param [in] data The data to set for the descriptor.
 | 
				
			||||||
 | 
					 * @param [in] length The length of the data in bytes.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEDescriptor::setValue(const uint8_t* data, size_t length) {
 | 
				
			||||||
 | 
					    if (length > m_value.attr_max_len) {
 | 
				
			||||||
 | 
					        NIMBLE_LOGE(LOG_TAG, "Size %d too large, must be no bigger than %d", length, m_value.attr_max_len);
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ble_npl_hw_enter_critical();
 | 
				
			||||||
 | 
					    m_value.attr_len = length;
 | 
				
			||||||
 | 
					    memcpy(m_value.attr_value, data, length);
 | 
				
			||||||
 | 
					    ble_npl_hw_exit_critical(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // setValue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set the value of the descriptor.
 | 
				
			||||||
 | 
					 * @param [in] value The value of the descriptor in string form.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEDescriptor::setValue(const std::string &value) {
 | 
				
			||||||
 | 
					    setValue((uint8_t*) value.data(), value.length());
 | 
				
			||||||
 | 
					} // setValue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set the characteristic this descriptor belongs to.
 | 
				
			||||||
 | 
					 * @param [in] pChar A pointer to the characteristic this descriptior belongs to.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEDescriptor::setCharacteristic(NimBLECharacteristic* pChar) {
 | 
				
			||||||
 | 
					    m_pCharacteristic = pChar;
 | 
				
			||||||
 | 
					} // setCharacteristic
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Return a string representation of the descriptor.
 | 
				
			||||||
 | 
					 * @return A string representation of the descriptor.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					std::string NimBLEDescriptor::toString() {
 | 
				
			||||||
 | 
					    char hex[5];
 | 
				
			||||||
 | 
					    snprintf(hex, sizeof(hex), "%04x", m_handle);
 | 
				
			||||||
 | 
					    std::string res = "UUID: " + m_uuid.toString() + ", handle: 0x" + hex;
 | 
				
			||||||
 | 
					    return res;
 | 
				
			||||||
 | 
					} // toString
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NimBLEDescriptorCallbacks::~NimBLEDescriptorCallbacks() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Callback function to support a read request.
 | 
				
			||||||
 | 
					 * @param [in] pDescriptor The descriptor that is the source of the event.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEDescriptorCallbacks::onRead(NimBLEDescriptor* pDescriptor) {
 | 
				
			||||||
 | 
					    (void)pDescriptor;
 | 
				
			||||||
 | 
					    NIMBLE_LOGD("NimBLEDescriptorCallbacks", "onRead: default");
 | 
				
			||||||
 | 
					} // onRead
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Callback function to support a write request.
 | 
				
			||||||
 | 
					 * @param [in] pDescriptor The descriptor that is the source of the event.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEDescriptorCallbacks::onWrite(NimBLEDescriptor* pDescriptor) {
 | 
				
			||||||
 | 
					    (void)pDescriptor;
 | 
				
			||||||
 | 
					    NIMBLE_LOGD("NimBLEDescriptorCallbacks", "onWrite: default");
 | 
				
			||||||
 | 
					} // onWrite
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_PERIPHERAL */
 | 
				
			||||||
							
								
								
									
										114
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEDescriptor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEDescriptor.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,114 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * NimBLEDescriptor.h
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created: on March 10, 2020
 | 
				
			||||||
 | 
					 *      Author H2zero
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Originally:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * BLEDescriptor.h
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created on: Jun 22, 2017
 | 
				
			||||||
 | 
					 *      Author: kolban
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef MAIN_NIMBLEDESCRIPTOR_H_
 | 
				
			||||||
 | 
					#define MAIN_NIMBLEDESCRIPTOR_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "nimconfig.h"
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "NimBLECharacteristic.h"
 | 
				
			||||||
 | 
					#include "NimBLEUUID.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint16_t attr_max_len;  /*!<  attribute max value length */
 | 
				
			||||||
 | 
					    uint16_t attr_len;      /*!<  attribute current value length */
 | 
				
			||||||
 | 
					    uint8_t  *attr_value;    /*!<  the pointer to attribute value */
 | 
				
			||||||
 | 
					} attr_value_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class NimBLEService;
 | 
				
			||||||
 | 
					class NimBLECharacteristic;
 | 
				
			||||||
 | 
					class NimBLEDescriptorCallbacks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief A model of a %BLE descriptor.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class NimBLEDescriptor {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    NimBLEDescriptor(const char* uuid, uint16_t properties,
 | 
				
			||||||
 | 
					                     uint16_t max_len,
 | 
				
			||||||
 | 
					                     NimBLECharacteristic* pCharacteristic = nullptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NimBLEDescriptor(NimBLEUUID uuid, uint16_t properties,
 | 
				
			||||||
 | 
					                     uint16_t max_len,
 | 
				
			||||||
 | 
					                     NimBLECharacteristic* pCharacteristic = nullptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ~NimBLEDescriptor();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint16_t              getHandle();
 | 
				
			||||||
 | 
					    NimBLEUUID            getUUID();
 | 
				
			||||||
 | 
					    std::string           toString();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void                  setCallbacks(NimBLEDescriptorCallbacks* pCallbacks);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    size_t                getLength();
 | 
				
			||||||
 | 
					    uint8_t*              getValue();
 | 
				
			||||||
 | 
					    std::string           getStringValue();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void                  setValue(const uint8_t* data, size_t size);
 | 
				
			||||||
 | 
					    void                  setValue(const std::string &value);
 | 
				
			||||||
 | 
					    NimBLECharacteristic* getCharacteristic();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Convenience template to set the descriptor value to <type\>val.
 | 
				
			||||||
 | 
					     * @param [in] s The value to set.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    template<typename T>
 | 
				
			||||||
 | 
					    void setValue(const T &s) {
 | 
				
			||||||
 | 
					        setValue((uint8_t*)&s, sizeof(T));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    friend class NimBLECharacteristic;
 | 
				
			||||||
 | 
					    friend class NimBLEService;
 | 
				
			||||||
 | 
					    friend class NimBLE2904;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static int handleGapEvent(uint16_t conn_handle, uint16_t attr_handle,
 | 
				
			||||||
 | 
					                              struct ble_gatt_access_ctxt *ctxt, void *arg);
 | 
				
			||||||
 | 
					    void       setHandle(uint16_t handle);
 | 
				
			||||||
 | 
					    void       setCharacteristic(NimBLECharacteristic* pChar);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NimBLEUUID                 m_uuid;
 | 
				
			||||||
 | 
					    uint16_t                   m_handle;
 | 
				
			||||||
 | 
					    NimBLEDescriptorCallbacks* m_pCallbacks;
 | 
				
			||||||
 | 
					    NimBLECharacteristic*      m_pCharacteristic;
 | 
				
			||||||
 | 
					    uint8_t                    m_properties;
 | 
				
			||||||
 | 
					    attr_value_t               m_value;
 | 
				
			||||||
 | 
					    uint8_t                    m_removed;
 | 
				
			||||||
 | 
					}; // NimBLEDescriptor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Callbacks that can be associated with a %BLE descriptors to inform of events.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * When a server application creates a %BLE descriptor, we may wish to be informed when there is either
 | 
				
			||||||
 | 
					 * a read or write request to the descriptors value.  An application can register a
 | 
				
			||||||
 | 
					 * sub-classed instance of this class and will be notified when such an event happens.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class NimBLEDescriptorCallbacks {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    virtual ~NimBLEDescriptorCallbacks();
 | 
				
			||||||
 | 
					    virtual void onRead(NimBLEDescriptor* pDescriptor);
 | 
				
			||||||
 | 
					    virtual void onWrite(NimBLEDescriptor* pDescriptor);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "NimBLE2904.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_PERIPHERAL */
 | 
				
			||||||
 | 
					#endif /* MAIN_NIMBLEDESCRIPTOR_H_ */
 | 
				
			||||||
							
								
								
									
										1159
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEDevice.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1159
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEDevice.cpp
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										218
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEDevice.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										218
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEDevice.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,218 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * NimBLEDevice.h
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created: on Jan 24 2020
 | 
				
			||||||
 | 
					 *      Author H2zero
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Originally:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * BLEDevice.h
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created on: Mar 16, 2017
 | 
				
			||||||
 | 
					 *      Author: kolban
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef MAIN_NIMBLEDEVICE_H_
 | 
				
			||||||
 | 
					#define MAIN_NIMBLEDEVICE_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "nimconfig.h"
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_ENABLED)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
 | 
				
			||||||
 | 
					#include "NimBLEScan.h"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER)
 | 
				
			||||||
 | 
					#include "NimBLEAdvertising.h"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
 | 
				
			||||||
 | 
					#include "NimBLEClient.h"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
 | 
				
			||||||
 | 
					#include "NimBLEServer.h"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "NimBLEUtils.h"
 | 
				
			||||||
 | 
					#include "NimBLESecurity.h"
 | 
				
			||||||
 | 
					#include "NimBLEAddress.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef ESP_PLATFORM
 | 
				
			||||||
 | 
					#  include "esp_bt.h"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <map>
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					#include <list>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define BLEDevice                       NimBLEDevice
 | 
				
			||||||
 | 
					#define BLEClient                       NimBLEClient
 | 
				
			||||||
 | 
					#define BLERemoteService                NimBLERemoteService
 | 
				
			||||||
 | 
					#define BLERemoteCharacteristic         NimBLERemoteCharacteristic
 | 
				
			||||||
 | 
					#define BLERemoteDescriptor             NimBLERemoteDescriptor
 | 
				
			||||||
 | 
					#define BLEAdvertisedDevice             NimBLEAdvertisedDevice
 | 
				
			||||||
 | 
					#define BLEScan                         NimBLEScan
 | 
				
			||||||
 | 
					#define BLEUUID                         NimBLEUUID
 | 
				
			||||||
 | 
					#define BLESecurity                     NimBLESecurity
 | 
				
			||||||
 | 
					#define BLESecurityCallbacks            NimBLESecurityCallbacks
 | 
				
			||||||
 | 
					#define BLEAddress                      NimBLEAddress
 | 
				
			||||||
 | 
					#define BLEUtils                        NimBLEUtils
 | 
				
			||||||
 | 
					#define BLEClientCallbacks              NimBLEClientCallbacks
 | 
				
			||||||
 | 
					#define BLEAdvertisedDeviceCallbacks    NimBLEAdvertisedDeviceCallbacks
 | 
				
			||||||
 | 
					#define BLEScanResults                  NimBLEScanResults
 | 
				
			||||||
 | 
					#define BLEServer                       NimBLEServer
 | 
				
			||||||
 | 
					#define BLEService                      NimBLEService
 | 
				
			||||||
 | 
					#define BLECharacteristic               NimBLECharacteristic
 | 
				
			||||||
 | 
					#define BLEAdvertising                  NimBLEAdvertising
 | 
				
			||||||
 | 
					#define BLEServerCallbacks              NimBLEServerCallbacks
 | 
				
			||||||
 | 
					#define BLECharacteristicCallbacks      NimBLECharacteristicCallbacks
 | 
				
			||||||
 | 
					#define BLEAdvertisementData            NimBLEAdvertisementData
 | 
				
			||||||
 | 
					#define BLEDescriptor                   NimBLEDescriptor
 | 
				
			||||||
 | 
					#define BLE2902                         NimBLE2902
 | 
				
			||||||
 | 
					#define BLE2904                         NimBLE2904
 | 
				
			||||||
 | 
					#define BLEDescriptorCallbacks          NimBLEDescriptorCallbacks
 | 
				
			||||||
 | 
					#define BLEBeacon                       NimBLEBeacon
 | 
				
			||||||
 | 
					#define BLEEddystoneTLM                 NimBLEEddystoneTLM
 | 
				
			||||||
 | 
					#define BLEEddystoneURL                 NimBLEEddystoneURL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_BT_NIMBLE_MAX_CONNECTIONS
 | 
				
			||||||
 | 
					#define NIMBLE_MAX_CONNECTIONS          CONFIG_BT_NIMBLE_MAX_CONNECTIONS
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define NIMBLE_MAX_CONNECTIONS          CONFIG_NIMBLE_MAX_CONNECTIONS
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef int (*gap_event_handler)(ble_gap_event *event, void *arg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern "C" void ble_store_config_init(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief A model of a %BLE Device from which all the BLE roles are created.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class NimBLEDevice {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    static void             init(const std::string &deviceName);
 | 
				
			||||||
 | 
					    static void             deinit(bool clearAll = false);
 | 
				
			||||||
 | 
					    static bool             getInitialized();
 | 
				
			||||||
 | 
					    static NimBLEAddress    getAddress();
 | 
				
			||||||
 | 
					    static std::string      toString();
 | 
				
			||||||
 | 
					    static bool             whiteListAdd(const NimBLEAddress & address);
 | 
				
			||||||
 | 
					    static bool             whiteListRemove(const NimBLEAddress & address);
 | 
				
			||||||
 | 
					    static bool             onWhiteList(const NimBLEAddress & address);
 | 
				
			||||||
 | 
					    static size_t           getWhiteListCount();
 | 
				
			||||||
 | 
					    static NimBLEAddress    getWhiteListAddress(size_t index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
 | 
				
			||||||
 | 
					    static NimBLEScan*      getScan();
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
 | 
				
			||||||
 | 
					    static NimBLEServer*    createServer();
 | 
				
			||||||
 | 
					    static NimBLEServer*    getServer();
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef ESP_PLATFORM
 | 
				
			||||||
 | 
					    static void             setPower(esp_power_level_t powerLevel, esp_ble_power_type_t powerType=ESP_BLE_PWR_TYPE_DEFAULT);
 | 
				
			||||||
 | 
					    static int              getPower(esp_ble_power_type_t powerType=ESP_BLE_PWR_TYPE_DEFAULT);
 | 
				
			||||||
 | 
					    static void             setOwnAddrType(uint8_t own_addr_type, bool useNRPA=false);
 | 
				
			||||||
 | 
					    static void             setScanDuplicateCacheSize(uint16_t cacheSize);
 | 
				
			||||||
 | 
					    static void             setScanFilterMode(uint8_t type);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					    static void             setPower(int dbm);
 | 
				
			||||||
 | 
					    static int              getPower();
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static void             setCustomGapHandler(gap_event_handler handler);
 | 
				
			||||||
 | 
					    static void             setSecurityAuth(bool bonding, bool mitm, bool sc);
 | 
				
			||||||
 | 
					    static void             setSecurityAuth(uint8_t auth_req);
 | 
				
			||||||
 | 
					    static void             setSecurityIOCap(uint8_t iocap);
 | 
				
			||||||
 | 
					    static void             setSecurityInitKey(uint8_t init_key);
 | 
				
			||||||
 | 
					    static void             setSecurityRespKey(uint8_t init_key);
 | 
				
			||||||
 | 
					    static void             setSecurityPasskey(uint32_t pin);
 | 
				
			||||||
 | 
					    static uint32_t         getSecurityPasskey();
 | 
				
			||||||
 | 
					    static void             setSecurityCallbacks(NimBLESecurityCallbacks* pCallbacks);
 | 
				
			||||||
 | 
					    static int              startSecurity(uint16_t conn_id);
 | 
				
			||||||
 | 
					    static int              setMTU(uint16_t mtu);
 | 
				
			||||||
 | 
					    static uint16_t         getMTU();
 | 
				
			||||||
 | 
					    static bool             isIgnored(const NimBLEAddress &address);
 | 
				
			||||||
 | 
					    static void             addIgnored(const NimBLEAddress &address);
 | 
				
			||||||
 | 
					    static void             removeIgnored(const NimBLEAddress &address);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER)
 | 
				
			||||||
 | 
					    static NimBLEAdvertising* getAdvertising();
 | 
				
			||||||
 | 
					    static void               startAdvertising();
 | 
				
			||||||
 | 
					    static void               stopAdvertising();
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
 | 
				
			||||||
 | 
					    static NimBLEClient*    createClient(NimBLEAddress peerAddress = NimBLEAddress(""));
 | 
				
			||||||
 | 
					    static bool             deleteClient(NimBLEClient* pClient);
 | 
				
			||||||
 | 
					    static NimBLEClient*    getClientByID(uint16_t conn_id);
 | 
				
			||||||
 | 
					    static NimBLEClient*    getClientByPeerAddress(const NimBLEAddress &peer_addr);
 | 
				
			||||||
 | 
					    static NimBLEClient*    getDisconnectedClient();
 | 
				
			||||||
 | 
					    static size_t           getClientListSize();
 | 
				
			||||||
 | 
					    static std::list<NimBLEClient*>* getClientList();
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) || defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
 | 
				
			||||||
 | 
					    static bool             deleteBond(const NimBLEAddress &address);
 | 
				
			||||||
 | 
					    static int              getNumBonds();
 | 
				
			||||||
 | 
					    static bool             isBonded(const NimBLEAddress &address);
 | 
				
			||||||
 | 
					    static void             deleteAllBonds();
 | 
				
			||||||
 | 
					    static NimBLEAddress    getBondedAddress(int index);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
 | 
				
			||||||
 | 
					    friend class NimBLEClient;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
 | 
				
			||||||
 | 
					    friend class NimBLEScan;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
 | 
				
			||||||
 | 
					    friend class NimBLEServer;
 | 
				
			||||||
 | 
					    friend class NimBLECharacteristic;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER)
 | 
				
			||||||
 | 
					    friend class NimBLEAdvertising;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static void        onReset(int reason);
 | 
				
			||||||
 | 
					    static void        onSync(void);
 | 
				
			||||||
 | 
					    static void        host_task(void *param);
 | 
				
			||||||
 | 
					    static bool        m_synced;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
 | 
				
			||||||
 | 
					    static NimBLEScan*                m_pScan;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
 | 
				
			||||||
 | 
					    static NimBLEServer*              m_pServer;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER)
 | 
				
			||||||
 | 
					    static NimBLEAdvertising*         m_bleAdvertising;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
 | 
				
			||||||
 | 
					    static std::list <NimBLEClient*>  m_cList;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    static std::list <NimBLEAddress>  m_ignoreList;
 | 
				
			||||||
 | 
					    static NimBLESecurityCallbacks*   m_securityCallbacks;
 | 
				
			||||||
 | 
					    static uint32_t                   m_passkey;
 | 
				
			||||||
 | 
					    static ble_gap_event_listener     m_listener;
 | 
				
			||||||
 | 
					    static gap_event_handler          m_customGapHandler;
 | 
				
			||||||
 | 
					    static uint8_t                    m_own_addr_type;
 | 
				
			||||||
 | 
					#ifdef ESP_PLATFORM
 | 
				
			||||||
 | 
					    static uint16_t                   m_scanDuplicateSize;
 | 
				
			||||||
 | 
					    static uint8_t                    m_scanFilterMode;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    static std::vector<NimBLEAddress> m_whiteList;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // CONFIG_BT_ENABLED
 | 
				
			||||||
 | 
					#endif // MAIN_NIMBLEDEVICE_H_
 | 
				
			||||||
							
								
								
									
										227
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEEddystoneTLM.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										227
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEEddystoneTLM.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,227 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * NimBLEEddystoneTLM.cpp
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created: on March 15 2020
 | 
				
			||||||
 | 
					 *      Author H2zero
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Originally:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * BLEEddystoneTLM.cpp
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created on: Mar 12, 2018
 | 
				
			||||||
 | 
					 *      Author: pcbreflux
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "nimconfig.h"
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_ENABLED)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "NimBLEEddystoneTLM.h"
 | 
				
			||||||
 | 
					#include "NimBLELog.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <cstring>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ENDIAN_CHANGE_U16(x) ((((x)&0xFF00)>>8) + (((x)&0xFF)<<8))
 | 
				
			||||||
 | 
					#define ENDIAN_CHANGE_U32(x) ((((x)&0xFF000000)>>24) + (((x)&0x00FF0000)>>8)) + ((((x)&0xFF00)<<8) + (((x)&0xFF)<<24))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char LOG_TAG[] = "NimBLEEddystoneTLM";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Construct a default EddystoneTLM beacon object.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEEddystoneTLM::NimBLEEddystoneTLM() {
 | 
				
			||||||
 | 
					    beaconUUID = 0xFEAA;
 | 
				
			||||||
 | 
					    m_eddystoneData.frameType = EDDYSTONE_TLM_FRAME_TYPE;
 | 
				
			||||||
 | 
					    m_eddystoneData.version = 0;
 | 
				
			||||||
 | 
					    m_eddystoneData.volt = 3300; // 3300mV = 3.3V
 | 
				
			||||||
 | 
					    m_eddystoneData.temp = (uint16_t) ((float) 23.00 * 256); // 8.8 fixed format
 | 
				
			||||||
 | 
					    m_eddystoneData.advCount = 0;
 | 
				
			||||||
 | 
					    m_eddystoneData.tmil = 0;
 | 
				
			||||||
 | 
					} // NimBLEEddystoneTLM
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Retrieve the data that is being advertised.
 | 
				
			||||||
 | 
					 * @return The advertised data.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					std::string NimBLEEddystoneTLM::getData() {
 | 
				
			||||||
 | 
					    return std::string((char*) &m_eddystoneData, sizeof(m_eddystoneData));
 | 
				
			||||||
 | 
					} // getData
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the UUID being advertised.
 | 
				
			||||||
 | 
					 * @return The UUID advertised.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEUUID NimBLEEddystoneTLM::getUUID() {
 | 
				
			||||||
 | 
					    return NimBLEUUID(beaconUUID);
 | 
				
			||||||
 | 
					} // getUUID
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the version being advertised.
 | 
				
			||||||
 | 
					 * @return The version number.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint8_t NimBLEEddystoneTLM::getVersion() {
 | 
				
			||||||
 | 
					    return m_eddystoneData.version;
 | 
				
			||||||
 | 
					} // getVersion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the battery voltage.
 | 
				
			||||||
 | 
					 * @return The battery voltage.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint16_t NimBLEEddystoneTLM::getVolt() {
 | 
				
			||||||
 | 
					    return ENDIAN_CHANGE_U16(m_eddystoneData.volt);
 | 
				
			||||||
 | 
					} // getVolt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the temperature being advertised.
 | 
				
			||||||
 | 
					 * @return The temperature value.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					float NimBLEEddystoneTLM::getTemp() {
 | 
				
			||||||
 | 
					    return ENDIAN_CHANGE_U16(m_eddystoneData.temp) / 256.0f;
 | 
				
			||||||
 | 
					} // getTemp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the count of advertisments sent.
 | 
				
			||||||
 | 
					 * @return The number of advertisments.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint32_t NimBLEEddystoneTLM::getCount() {
 | 
				
			||||||
 | 
					    return ENDIAN_CHANGE_U32(m_eddystoneData.advCount);
 | 
				
			||||||
 | 
					} // getCount
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the advertisment time.
 | 
				
			||||||
 | 
					 * @return The advertisment time.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint32_t NimBLEEddystoneTLM::getTime() {
 | 
				
			||||||
 | 
					    return (ENDIAN_CHANGE_U32(m_eddystoneData.tmil)) / 10;
 | 
				
			||||||
 | 
					} // getTime
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get a string representation of the beacon.
 | 
				
			||||||
 | 
					 * @return The string representation.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					std::string NimBLEEddystoneTLM::toString() {
 | 
				
			||||||
 | 
					  std::string out = "";
 | 
				
			||||||
 | 
					  uint32_t rawsec = ENDIAN_CHANGE_U32(m_eddystoneData.tmil);
 | 
				
			||||||
 | 
					  char val[12];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  out += "Version "; // + std::string(m_eddystoneData.version);
 | 
				
			||||||
 | 
					  snprintf(val, sizeof(val), "%d", m_eddystoneData.version);
 | 
				
			||||||
 | 
					  out += val;
 | 
				
			||||||
 | 
					  out += "\n";
 | 
				
			||||||
 | 
					  out += "Battery Voltage "; // + ENDIAN_CHANGE_U16(m_eddystoneData.volt);
 | 
				
			||||||
 | 
					  snprintf(val, sizeof(val), "%d", ENDIAN_CHANGE_U16(m_eddystoneData.volt));
 | 
				
			||||||
 | 
					  out += val;
 | 
				
			||||||
 | 
					  out += " mV\n";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  out += "Temperature ";
 | 
				
			||||||
 | 
					  snprintf(val, sizeof(val), "%.2f", ENDIAN_CHANGE_U16(m_eddystoneData.temp) / 256.0f);
 | 
				
			||||||
 | 
					  out += val;
 | 
				
			||||||
 | 
					  out += " C\n";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  out += "Adv. Count ";
 | 
				
			||||||
 | 
					  snprintf(val, sizeof(val), "%" PRIu32, ENDIAN_CHANGE_U32(m_eddystoneData.advCount));
 | 
				
			||||||
 | 
					  out += val;
 | 
				
			||||||
 | 
					  out += "\n";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  out += "Time in seconds ";
 | 
				
			||||||
 | 
					  snprintf(val, sizeof(val), "%" PRIu32, rawsec/10);
 | 
				
			||||||
 | 
					  out += val;
 | 
				
			||||||
 | 
					  out += "\n";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  out += "Time ";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  snprintf(val, sizeof(val), "%04" PRIu32, rawsec / 864000);
 | 
				
			||||||
 | 
					  out += val;
 | 
				
			||||||
 | 
					  out += ".";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  snprintf(val, sizeof(val), "%02" PRIu32, (rawsec / 36000) % 24);
 | 
				
			||||||
 | 
					  out += val;
 | 
				
			||||||
 | 
					  out += ":";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  snprintf(val, sizeof(val), "%02" PRIu32, (rawsec / 600) % 60);
 | 
				
			||||||
 | 
					  out += val;
 | 
				
			||||||
 | 
					  out += ":";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  snprintf(val, sizeof(val), "%02" PRIu32, (rawsec / 10) % 60);
 | 
				
			||||||
 | 
					  out += val;
 | 
				
			||||||
 | 
					  out += "\n";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return out;
 | 
				
			||||||
 | 
					} // toString
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set the raw data for the beacon advertisment.
 | 
				
			||||||
 | 
					 * @param [in] data The raw data to advertise.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEEddystoneTLM::setData(const std::string &data) {
 | 
				
			||||||
 | 
					    if (data.length() != sizeof(m_eddystoneData)) {
 | 
				
			||||||
 | 
					        NIMBLE_LOGE(LOG_TAG, "Unable to set the data ... length passed in was %d and expected %d",
 | 
				
			||||||
 | 
					                                                data.length(), sizeof(m_eddystoneData));
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  memcpy(&m_eddystoneData, data.data(), data.length());
 | 
				
			||||||
 | 
					} // setData
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set the UUID to advertise.
 | 
				
			||||||
 | 
					 * @param [in] l_uuid The UUID.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEEddystoneTLM::setUUID(const NimBLEUUID &l_uuid) {
 | 
				
			||||||
 | 
					    beaconUUID = l_uuid.getNative()->u16.value;
 | 
				
			||||||
 | 
					} // setUUID
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set the version to advertise.
 | 
				
			||||||
 | 
					 * @param [in] version The version number.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEEddystoneTLM::setVersion(uint8_t version) {
 | 
				
			||||||
 | 
					    m_eddystoneData.version = version;
 | 
				
			||||||
 | 
					} // setVersion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set the battery voltage to advertise.
 | 
				
			||||||
 | 
					 * @param [in] volt The voltage in millivolts.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEEddystoneTLM::setVolt(uint16_t volt) {
 | 
				
			||||||
 | 
					    m_eddystoneData.volt = volt;
 | 
				
			||||||
 | 
					} // setVolt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set the temperature to advertise.
 | 
				
			||||||
 | 
					 * @param [in] temp The temperature value.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEEddystoneTLM::setTemp(float temp) {
 | 
				
			||||||
 | 
					    m_eddystoneData.temp = (uint16_t)temp;
 | 
				
			||||||
 | 
					} // setTemp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set the advertisment count.
 | 
				
			||||||
 | 
					 * @param [in] advCount The advertisment number.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEEddystoneTLM::setCount(uint32_t advCount) {
 | 
				
			||||||
 | 
					    m_eddystoneData.advCount = advCount;
 | 
				
			||||||
 | 
					} // setCount
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set the advertisment time.
 | 
				
			||||||
 | 
					 * @param [in] tmil The advertisment time in milliseconds.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEEddystoneTLM::setTime(uint32_t tmil) {
 | 
				
			||||||
 | 
					    m_eddystoneData.tmil = tmil;
 | 
				
			||||||
 | 
					} // setTime
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										61
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEEddystoneTLM.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEEddystoneTLM.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * NimBLEEddystoneTLM.h
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created: on March 15 2020
 | 
				
			||||||
 | 
					 *      Author H2zero
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Originally:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * BLEEddystoneTLM.h
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created on: Mar 12, 2018
 | 
				
			||||||
 | 
					 *      Author: pcbreflux
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef _NimBLEEddystoneTLM_H_
 | 
				
			||||||
 | 
					#define _NimBLEEddystoneTLM_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "NimBLEUUID.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define EDDYSTONE_TLM_FRAME_TYPE 0x20
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Representation of a beacon.
 | 
				
			||||||
 | 
					 * See:
 | 
				
			||||||
 | 
					 * * https://github.com/google/eddystone
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class NimBLEEddystoneTLM {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    NimBLEEddystoneTLM();
 | 
				
			||||||
 | 
					    std::string getData();
 | 
				
			||||||
 | 
					    NimBLEUUID   getUUID();
 | 
				
			||||||
 | 
					    uint8_t  getVersion();
 | 
				
			||||||
 | 
					    uint16_t    getVolt();
 | 
				
			||||||
 | 
					    float      getTemp();
 | 
				
			||||||
 | 
					    uint32_t    getCount();
 | 
				
			||||||
 | 
					    uint32_t    getTime();
 | 
				
			||||||
 | 
					    std::string toString();
 | 
				
			||||||
 | 
					    void        setData(const std::string &data);
 | 
				
			||||||
 | 
					    void        setUUID(const NimBLEUUID &l_uuid);
 | 
				
			||||||
 | 
					    void        setVersion(uint8_t version);
 | 
				
			||||||
 | 
					    void        setVolt(uint16_t volt);
 | 
				
			||||||
 | 
					    void        setTemp(float temp);
 | 
				
			||||||
 | 
					    void        setCount(uint32_t advCount);
 | 
				
			||||||
 | 
					    void        setTime(uint32_t tmil);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    uint16_t beaconUUID;
 | 
				
			||||||
 | 
					    struct {
 | 
				
			||||||
 | 
					        uint8_t frameType;
 | 
				
			||||||
 | 
					        uint8_t version;
 | 
				
			||||||
 | 
					        uint16_t volt;
 | 
				
			||||||
 | 
					        uint16_t temp;
 | 
				
			||||||
 | 
					        uint32_t advCount;
 | 
				
			||||||
 | 
					        uint32_t tmil;
 | 
				
			||||||
 | 
					    } __attribute__((packed)) m_eddystoneData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}; // NimBLEEddystoneTLM
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* _NimBLEEddystoneTLM_H_ */
 | 
				
			||||||
							
								
								
									
										204
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEEddystoneURL.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										204
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEEddystoneURL.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,204 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * NimBLEEddystoneURL.cpp
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created: on March 15 2020
 | 
				
			||||||
 | 
					 *      Author H2zero
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Originally:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * BLEEddystoneURL.cpp
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created on: Mar 12, 2018
 | 
				
			||||||
 | 
					 *      Author: pcbreflux
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#include "nimconfig.h"
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_ENABLED)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "NimBLEEddystoneURL.h"
 | 
				
			||||||
 | 
					#include "NimBLELog.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <cstring>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char LOG_TAG[] = "NimBLEEddystoneURL";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Construct a default EddystoneURL beacon object.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEEddystoneURL::NimBLEEddystoneURL() {
 | 
				
			||||||
 | 
					    beaconUUID = 0xFEAA;
 | 
				
			||||||
 | 
					    lengthURL = 0;
 | 
				
			||||||
 | 
					    m_eddystoneData.frameType = EDDYSTONE_URL_FRAME_TYPE;
 | 
				
			||||||
 | 
					    m_eddystoneData.advertisedTxPower = 0;
 | 
				
			||||||
 | 
					    memset(m_eddystoneData.url, 0, sizeof(m_eddystoneData.url));
 | 
				
			||||||
 | 
					} // BLEEddystoneURL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Retrieve the data that is being advertised.
 | 
				
			||||||
 | 
					 * @return The advertised data.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					std::string NimBLEEddystoneURL::getData() {
 | 
				
			||||||
 | 
					    return std::string((char*) &m_eddystoneData, sizeof(m_eddystoneData));
 | 
				
			||||||
 | 
					} // getData
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the UUID being advertised.
 | 
				
			||||||
 | 
					 * @return The UUID advertised.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEUUID NimBLEEddystoneURL::getUUID() {
 | 
				
			||||||
 | 
					    return NimBLEUUID(beaconUUID);
 | 
				
			||||||
 | 
					} // getUUID
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the transmit power being advertised.
 | 
				
			||||||
 | 
					 * @return The transmit power.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int8_t NimBLEEddystoneURL::getPower() {
 | 
				
			||||||
 | 
					    return m_eddystoneData.advertisedTxPower;
 | 
				
			||||||
 | 
					} // getPower
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the raw URL being advertised.
 | 
				
			||||||
 | 
					 * @return The raw URL.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					std::string NimBLEEddystoneURL::getURL() {
 | 
				
			||||||
 | 
					    return std::string((char*) &m_eddystoneData.url, sizeof(m_eddystoneData.url));
 | 
				
			||||||
 | 
					} // getURL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the full URL being advertised.
 | 
				
			||||||
 | 
					 * @return The full URL.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					std::string NimBLEEddystoneURL::getDecodedURL() {
 | 
				
			||||||
 | 
					    std::string decodedURL = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    switch (m_eddystoneData.url[0]) {
 | 
				
			||||||
 | 
					        case 0x00:
 | 
				
			||||||
 | 
					            decodedURL += "http://www.";
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case 0x01:
 | 
				
			||||||
 | 
					            decodedURL += "https://www.";
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case 0x02:
 | 
				
			||||||
 | 
					            decodedURL += "http://";
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case 0x03:
 | 
				
			||||||
 | 
					            decodedURL += "https://";
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        default:
 | 
				
			||||||
 | 
					            decodedURL += m_eddystoneData.url[0];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (int i = 1; i < lengthURL; i++) {
 | 
				
			||||||
 | 
					        if (m_eddystoneData.url[i] > 33 && m_eddystoneData.url[i] < 127) {
 | 
				
			||||||
 | 
					            decodedURL += m_eddystoneData.url[i];
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            switch (m_eddystoneData.url[i]) {
 | 
				
			||||||
 | 
					                case 0x00:
 | 
				
			||||||
 | 
					                    decodedURL += ".com/";
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                case 0x01:
 | 
				
			||||||
 | 
					                    decodedURL += ".org/";
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                case 0x02:
 | 
				
			||||||
 | 
					                    decodedURL += ".edu/";
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                case 0x03:
 | 
				
			||||||
 | 
					                    decodedURL += ".net/";
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                case 0x04:
 | 
				
			||||||
 | 
					                    decodedURL += ".info/";
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                case 0x05:
 | 
				
			||||||
 | 
					                    decodedURL += ".biz/";
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                case 0x06:
 | 
				
			||||||
 | 
					                    decodedURL += ".gov/";
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                case 0x07:
 | 
				
			||||||
 | 
					                    decodedURL += ".com";
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                case 0x08:
 | 
				
			||||||
 | 
					                    decodedURL += ".org";
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                case 0x09:
 | 
				
			||||||
 | 
					                    decodedURL += ".edu";
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                case 0x0A:
 | 
				
			||||||
 | 
					                    decodedURL += ".net";
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                case 0x0B:
 | 
				
			||||||
 | 
					                    decodedURL += ".info";
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                case 0x0C:
 | 
				
			||||||
 | 
					                    decodedURL += ".biz";
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                case 0x0D:
 | 
				
			||||||
 | 
					                    decodedURL += ".gov";
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                default:
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return decodedURL;
 | 
				
			||||||
 | 
					} // getDecodedURL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set the raw data for the beacon advertisment.
 | 
				
			||||||
 | 
					 * @param [in] data The raw data to advertise.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEEddystoneURL::setData(const std::string &data) {
 | 
				
			||||||
 | 
					    if (data.length() > sizeof(m_eddystoneData)) {
 | 
				
			||||||
 | 
					        NIMBLE_LOGE(LOG_TAG, "Unable to set the data ... length passed in was %d and max expected %d",
 | 
				
			||||||
 | 
					                                                    data.length(), sizeof(m_eddystoneData));
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    memset(&m_eddystoneData, 0, sizeof(m_eddystoneData));
 | 
				
			||||||
 | 
					    memcpy(&m_eddystoneData, data.data(), data.length());
 | 
				
			||||||
 | 
					    lengthURL = data.length() - (sizeof(m_eddystoneData) - sizeof(m_eddystoneData.url));
 | 
				
			||||||
 | 
					} // setData
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set the UUID to advertise.
 | 
				
			||||||
 | 
					 * @param [in] l_uuid The UUID.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEEddystoneURL::setUUID(const NimBLEUUID &l_uuid) {
 | 
				
			||||||
 | 
					    beaconUUID = l_uuid.getNative()->u16.value;
 | 
				
			||||||
 | 
					} // setUUID
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set the transmit power to advertise.
 | 
				
			||||||
 | 
					 * @param [in] advertisedTxPower The transmit power level.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEEddystoneURL::setPower(int8_t advertisedTxPower) {
 | 
				
			||||||
 | 
					    m_eddystoneData.advertisedTxPower = advertisedTxPower;
 | 
				
			||||||
 | 
					} // setPower
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set the URL to advertise.
 | 
				
			||||||
 | 
					 * @param [in] url The URL.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEEddystoneURL::setURL(const std::string &url) {
 | 
				
			||||||
 | 
					  if (url.length() > sizeof(m_eddystoneData.url)) {
 | 
				
			||||||
 | 
					    NIMBLE_LOGE(LOG_TAG, "Unable to set the url ... length passed in was %d and max expected %d",
 | 
				
			||||||
 | 
					                                                    url.length(), sizeof(m_eddystoneData.url));
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  memset(m_eddystoneData.url, 0, sizeof(m_eddystoneData.url));
 | 
				
			||||||
 | 
					  memcpy(m_eddystoneData.url, url.data(), url.length());
 | 
				
			||||||
 | 
					  lengthURL = url.length();
 | 
				
			||||||
 | 
					} // setURL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										52
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEEddystoneURL.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEEddystoneURL.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,52 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * NimBLEEddystoneURL.h
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created: on March 15 2020
 | 
				
			||||||
 | 
					 *      Author H2zero
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Originally:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * BLEEddystoneURL.h
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created on: Mar 12, 2018
 | 
				
			||||||
 | 
					 *      Author: pcbreflux
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef _NIMBLEEddystoneURL_H_
 | 
				
			||||||
 | 
					#define _NIMBLEEddystoneURL_H_
 | 
				
			||||||
 | 
					#include "NimBLEUUID.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define EDDYSTONE_URL_FRAME_TYPE 0x10
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Representation of a beacon.
 | 
				
			||||||
 | 
					 * See:
 | 
				
			||||||
 | 
					 * * https://github.com/google/eddystone
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class NimBLEEddystoneURL {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    NimBLEEddystoneURL();
 | 
				
			||||||
 | 
					    std::string getData();
 | 
				
			||||||
 | 
					    NimBLEUUID   getUUID();
 | 
				
			||||||
 | 
					    int8_t    getPower();
 | 
				
			||||||
 | 
					    std::string getURL();
 | 
				
			||||||
 | 
					    std::string getDecodedURL();
 | 
				
			||||||
 | 
					    void        setData(const std::string &data);
 | 
				
			||||||
 | 
					    void        setUUID(const NimBLEUUID &l_uuid);
 | 
				
			||||||
 | 
					    void        setPower(int8_t advertisedTxPower);
 | 
				
			||||||
 | 
					    void        setURL(const std::string &url);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    uint16_t beaconUUID;
 | 
				
			||||||
 | 
					    uint8_t  lengthURL;
 | 
				
			||||||
 | 
					    struct {
 | 
				
			||||||
 | 
					        uint8_t frameType;
 | 
				
			||||||
 | 
					        int8_t  advertisedTxPower;
 | 
				
			||||||
 | 
					        uint8_t url[16];
 | 
				
			||||||
 | 
					    } __attribute__((packed)) m_eddystoneData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}; // NIMBLEEddystoneURL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* _NIMBLEEddystoneURL_H_ */
 | 
				
			||||||
							
								
								
									
										248
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEHIDDevice.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										248
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEHIDDevice.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,248 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * NimBLEHIDDevice.cpp
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created: on Oct 06 2020
 | 
				
			||||||
 | 
					 *      Author wakwak-koba
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Originally:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * BLEHIDDevice.cpp
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created on: Jan 03, 2018
 | 
				
			||||||
 | 
					 *      Author: chegewara
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "nimconfig.h"
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "NimBLEHIDDevice.h"
 | 
				
			||||||
 | 
					#include "NimBLE2904.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Construct a default NimBLEHIDDevice object.
 | 
				
			||||||
 | 
					 * @param [in] server A pointer to the server instance this HID Device will use.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEHIDDevice::NimBLEHIDDevice(NimBLEServer* server) {
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Here we create mandatory services described in bluetooth specification
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						m_deviceInfoService = server->createService(NimBLEUUID((uint16_t) 0x180a));
 | 
				
			||||||
 | 
						m_hidService = server->createService(NimBLEUUID((uint16_t) 0x1812));
 | 
				
			||||||
 | 
						m_batteryService = server->createService(NimBLEUUID((uint16_t) 0x180f));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Mandatory characteristic for device info service
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						m_pnpCharacteristic = m_deviceInfoService->createCharacteristic((uint16_t) 0x2a50, NIMBLE_PROPERTY::READ);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Mandatory characteristics for HID service
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						m_hidInfoCharacteristic = m_hidService->createCharacteristic((uint16_t) 0x2a4a, NIMBLE_PROPERTY::READ);
 | 
				
			||||||
 | 
						m_reportMapCharacteristic = m_hidService->createCharacteristic((uint16_t) 0x2a4b, NIMBLE_PROPERTY::READ);
 | 
				
			||||||
 | 
						m_hidControlCharacteristic = m_hidService->createCharacteristic((uint16_t) 0x2a4c, NIMBLE_PROPERTY::WRITE_NR);
 | 
				
			||||||
 | 
						m_protocolModeCharacteristic = m_hidService->createCharacteristic((uint16_t) 0x2a4e, NIMBLE_PROPERTY::WRITE_NR | NIMBLE_PROPERTY::READ);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Mandatory battery level characteristic with notification and presence descriptor
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						m_batteryLevelCharacteristic = m_batteryService->createCharacteristic((uint16_t) 0x2a19, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY);
 | 
				
			||||||
 | 
						NimBLE2904* batteryLevelDescriptor = (NimBLE2904*)m_batteryLevelCharacteristic->createDescriptor((uint16_t) 0x2904);
 | 
				
			||||||
 | 
						batteryLevelDescriptor->setFormat(NimBLE2904::FORMAT_UINT8);
 | 
				
			||||||
 | 
						batteryLevelDescriptor->setNamespace(1);
 | 
				
			||||||
 | 
						batteryLevelDescriptor->setUnit(0x27ad);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * This value is setup here because its default value in most usage cases, its very rare to use boot mode
 | 
				
			||||||
 | 
						 * and we want to simplify library using as much as possible
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						const uint8_t pMode[] = { 0x01 };
 | 
				
			||||||
 | 
						protocolMode()->setValue((uint8_t*) pMode, 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NimBLEHIDDevice::~NimBLEHIDDevice() {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set the report map data formatting information.
 | 
				
			||||||
 | 
					 * @param [in] map A pointer to an array with the values to set.
 | 
				
			||||||
 | 
					 * @param [in] size The number of values in the array.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEHIDDevice::reportMap(uint8_t* map, uint16_t size) {
 | 
				
			||||||
 | 
						m_reportMapCharacteristic->setValue(map, size);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Start the HID device services.\n
 | 
				
			||||||
 | 
					 * This function called when all the services have been created.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEHIDDevice::startServices() {
 | 
				
			||||||
 | 
						m_deviceInfoService->start();
 | 
				
			||||||
 | 
						m_hidService->start();
 | 
				
			||||||
 | 
						m_batteryService->start();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Create a manufacturer characteristic (this characteristic is optional).
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLECharacteristic* NimBLEHIDDevice::manufacturer() {
 | 
				
			||||||
 | 
						m_manufacturerCharacteristic = m_deviceInfoService->createCharacteristic((uint16_t) 0x2a29, NIMBLE_PROPERTY::READ);
 | 
				
			||||||
 | 
						return m_manufacturerCharacteristic;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set manufacturer name
 | 
				
			||||||
 | 
					 * @param [in] name The manufacturer name of this HID device.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEHIDDevice::manufacturer(std::string name) {
 | 
				
			||||||
 | 
						m_manufacturerCharacteristic->setValue(name);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Sets the Plug n Play characterisc value.
 | 
				
			||||||
 | 
					 * @param [in] sig The vendor ID source number.
 | 
				
			||||||
 | 
					 * @param [in] vid The vendor ID number.
 | 
				
			||||||
 | 
					 * @param [in] pid The product ID number.
 | 
				
			||||||
 | 
					 * @param [in] version The produce version number.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEHIDDevice::pnp(uint8_t sig, uint16_t vid, uint16_t pid, uint16_t version) {
 | 
				
			||||||
 | 
						uint8_t pnp[] = { sig, (uint8_t) (vid >> 8), (uint8_t) vid, (uint8_t) (pid >> 8), (uint8_t) pid, (uint8_t) (version >> 8), (uint8_t) version };
 | 
				
			||||||
 | 
						m_pnpCharacteristic->setValue(pnp, sizeof(pnp));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Sets the HID Information characteristic value.
 | 
				
			||||||
 | 
					 * @param [in] country The country code for the device.
 | 
				
			||||||
 | 
					 * @param [in] flags The HID Class Specification release number to use.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEHIDDevice::hidInfo(uint8_t country, uint8_t flags) {
 | 
				
			||||||
 | 
						uint8_t info[] = { 0x11, 0x1, country, flags };
 | 
				
			||||||
 | 
						m_hidInfoCharacteristic->setValue(info, sizeof(info));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Create input report characteristic
 | 
				
			||||||
 | 
					 * @param [in] reportID input report ID, the same as in report map for input object related to the characteristic
 | 
				
			||||||
 | 
					 * @return pointer to new input report characteristic
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLECharacteristic* NimBLEHIDDevice::inputReport(uint8_t reportID) {
 | 
				
			||||||
 | 
						NimBLECharacteristic* inputReportCharacteristic = m_hidService->createCharacteristic((uint16_t) 0x2a4d, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY | NIMBLE_PROPERTY::READ_ENC);
 | 
				
			||||||
 | 
						NimBLEDescriptor* inputReportDescriptor = inputReportCharacteristic->createDescriptor((uint16_t) 0x2908, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::READ_ENC);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint8_t desc1_val[] = { reportID, 0x01 };
 | 
				
			||||||
 | 
						inputReportDescriptor->setValue((uint8_t*) desc1_val, 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return inputReportCharacteristic;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Create output report characteristic
 | 
				
			||||||
 | 
					 * @param [in] reportID Output report ID, the same as in report map for output object related to the characteristic
 | 
				
			||||||
 | 
					 * @return Pointer to new output report characteristic
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLECharacteristic* NimBLEHIDDevice::outputReport(uint8_t reportID) {
 | 
				
			||||||
 | 
						NimBLECharacteristic* outputReportCharacteristic = m_hidService->createCharacteristic((uint16_t) 0x2a4d, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::WRITE_NR | NIMBLE_PROPERTY::READ_ENC | NIMBLE_PROPERTY::WRITE_ENC);
 | 
				
			||||||
 | 
						NimBLEDescriptor* outputReportDescriptor = outputReportCharacteristic->createDescriptor((uint16_t) 0x2908, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::READ_ENC | NIMBLE_PROPERTY::WRITE_ENC);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint8_t desc1_val[] = { reportID, 0x02 };
 | 
				
			||||||
 | 
						outputReportDescriptor->setValue((uint8_t*) desc1_val, 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return outputReportCharacteristic;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Create feature report characteristic.
 | 
				
			||||||
 | 
					 * @param [in] reportID Feature report ID, the same as in report map for feature object related to the characteristic
 | 
				
			||||||
 | 
					 * @return Pointer to new feature report characteristic
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLECharacteristic* NimBLEHIDDevice::featureReport(uint8_t reportID) {
 | 
				
			||||||
 | 
						NimBLECharacteristic* featureReportCharacteristic = m_hidService->createCharacteristic((uint16_t) 0x2a4d, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::READ_ENC | NIMBLE_PROPERTY::WRITE_ENC);
 | 
				
			||||||
 | 
						NimBLEDescriptor* featureReportDescriptor = featureReportCharacteristic->createDescriptor((uint16_t) 0x2908, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::READ_ENC | NIMBLE_PROPERTY::WRITE_ENC);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint8_t desc1_val[] = { reportID, 0x03 };
 | 
				
			||||||
 | 
						featureReportDescriptor->setValue((uint8_t*) desc1_val, 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return featureReportCharacteristic;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Creates a keyboard boot input report characteristic
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLECharacteristic* NimBLEHIDDevice::bootInput() {
 | 
				
			||||||
 | 
						return m_hidService->createCharacteristic((uint16_t) 0x2a22, NIMBLE_PROPERTY::NOTIFY);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Create a keyboard boot output report characteristic
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLECharacteristic* NimBLEHIDDevice::bootOutput() {
 | 
				
			||||||
 | 
						return m_hidService->createCharacteristic((uint16_t) 0x2a32, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::WRITE_NR);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Returns a pointer to the HID control point characteristic.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLECharacteristic* NimBLEHIDDevice::hidControl() {
 | 
				
			||||||
 | 
						return m_hidControlCharacteristic;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Returns a pointer to the protocol mode characteristic.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLECharacteristic* NimBLEHIDDevice::protocolMode() {
 | 
				
			||||||
 | 
						return m_protocolModeCharacteristic;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set the battery level characteristic value.
 | 
				
			||||||
 | 
					 * @param [in] level The battery level value.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEHIDDevice::setBatteryLevel(uint8_t level) {
 | 
				
			||||||
 | 
						m_batteryLevelCharacteristic->setValue(&level, 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * @brief Returns battery level characteristic
 | 
				
			||||||
 | 
					 * @ return battery level characteristic
 | 
				
			||||||
 | 
					 *//*
 | 
				
			||||||
 | 
					BLECharacteristic* BLEHIDDevice::batteryLevel() {
 | 
				
			||||||
 | 
						return m_batteryLevelCharacteristic;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BLECharacteristic*	 BLEHIDDevice::reportMap() {
 | 
				
			||||||
 | 
						return m_reportMapCharacteristic;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BLECharacteristic*	 BLEHIDDevice::pnp() {
 | 
				
			||||||
 | 
						return m_pnpCharacteristic;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BLECharacteristic*	BLEHIDDevice::hidInfo() {
 | 
				
			||||||
 | 
						return m_hidInfoCharacteristic;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Returns a pointer to the device information service.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEService* NimBLEHIDDevice::deviceInfo() {
 | 
				
			||||||
 | 
						return m_deviceInfoService;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Returns a pointer to the HID service.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEService* NimBLEHIDDevice::hidService() {
 | 
				
			||||||
 | 
						return m_hidService;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief @brief Returns a pointer to the battery service.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEService* NimBLEHIDDevice::batteryService() {
 | 
				
			||||||
 | 
						return m_batteryService;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_PERIPHERAL */
 | 
				
			||||||
							
								
								
									
										86
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEHIDDevice.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEHIDDevice.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,86 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * NimBLEHIDDevice.h
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created: on Oct 06 2020
 | 
				
			||||||
 | 
					 *      Author wakwak-koba
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Originally:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * BLEHIDDevice.h
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created on: Jan 03, 2018
 | 
				
			||||||
 | 
					 *      Author: chegewara
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef _BLEHIDDEVICE_H_
 | 
				
			||||||
 | 
					#define _BLEHIDDEVICE_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "nimconfig.h"
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "NimBLECharacteristic.h"
 | 
				
			||||||
 | 
					#include "NimBLEService.h"
 | 
				
			||||||
 | 
					#include "NimBLEDescriptor.h"
 | 
				
			||||||
 | 
					#include "HIDTypes.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GENERIC_HID		0x03C0
 | 
				
			||||||
 | 
					#define HID_KEYBOARD	   0x03C1
 | 
				
			||||||
 | 
					#define HID_MOUSE		  0x03C2
 | 
				
			||||||
 | 
					#define HID_JOYSTICK	   0x03C3
 | 
				
			||||||
 | 
					#define HID_GAMEPAD		0x03C4
 | 
				
			||||||
 | 
					#define HID_TABLET		 0x03C5
 | 
				
			||||||
 | 
					#define HID_CARD_READER	0x03C6
 | 
				
			||||||
 | 
					#define HID_DIGITAL_PEN	0x03C7
 | 
				
			||||||
 | 
					#define HID_BARCODE		0x03C8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief A model of a %BLE Human Interface Device.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class NimBLEHIDDevice {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						NimBLEHIDDevice(NimBLEServer*);
 | 
				
			||||||
 | 
						virtual ~NimBLEHIDDevice();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void reportMap(uint8_t* map, uint16_t);
 | 
				
			||||||
 | 
						void startServices();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						NimBLEService* deviceInfo();
 | 
				
			||||||
 | 
						NimBLEService* hidService();
 | 
				
			||||||
 | 
						NimBLEService* batteryService();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						NimBLECharacteristic* 	manufacturer();
 | 
				
			||||||
 | 
						void 	manufacturer(std::string name);
 | 
				
			||||||
 | 
						//NimBLECharacteristic* 	pnp();
 | 
				
			||||||
 | 
						void	pnp(uint8_t sig, uint16_t vid, uint16_t pid, uint16_t version);
 | 
				
			||||||
 | 
						//NimBLECharacteristic*	hidInfo();
 | 
				
			||||||
 | 
						void	hidInfo(uint8_t country, uint8_t flags);
 | 
				
			||||||
 | 
						//NimBLECharacteristic* 	batteryLevel();
 | 
				
			||||||
 | 
						void 	setBatteryLevel(uint8_t level);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//NimBLECharacteristic* 	reportMap();
 | 
				
			||||||
 | 
						NimBLECharacteristic* 	hidControl();
 | 
				
			||||||
 | 
						NimBLECharacteristic* 	inputReport(uint8_t reportID);
 | 
				
			||||||
 | 
						NimBLECharacteristic* 	outputReport(uint8_t reportID);
 | 
				
			||||||
 | 
						NimBLECharacteristic* 	featureReport(uint8_t reportID);
 | 
				
			||||||
 | 
						NimBLECharacteristic* 	protocolMode();
 | 
				
			||||||
 | 
						NimBLECharacteristic* 	bootInput();
 | 
				
			||||||
 | 
						NimBLECharacteristic* 	bootOutput();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
						NimBLEService*			m_deviceInfoService;			//0x180a
 | 
				
			||||||
 | 
						NimBLEService*			m_hidService;					//0x1812
 | 
				
			||||||
 | 
						NimBLEService*			m_batteryService = 0;			//0x180f
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						NimBLECharacteristic* 	m_manufacturerCharacteristic;	//0x2a29
 | 
				
			||||||
 | 
						NimBLECharacteristic* 	m_pnpCharacteristic;			//0x2a50
 | 
				
			||||||
 | 
						NimBLECharacteristic* 	m_hidInfoCharacteristic;		//0x2a4a
 | 
				
			||||||
 | 
						NimBLECharacteristic* 	m_reportMapCharacteristic;		//0x2a4b
 | 
				
			||||||
 | 
						NimBLECharacteristic* 	m_hidControlCharacteristic;		//0x2a4c
 | 
				
			||||||
 | 
						NimBLECharacteristic* 	m_protocolModeCharacteristic;	//0x2a4e
 | 
				
			||||||
 | 
						NimBLECharacteristic*	m_batteryLevelCharacteristic;	//0x2a19
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_BROADCASTER */
 | 
				
			||||||
 | 
					#endif /* _BLEHIDDEVICE_H_ */
 | 
				
			||||||
							
								
								
									
										80
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLELog.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLELog.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,80 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * NimBLELog.h
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created: on Feb 24 2020
 | 
				
			||||||
 | 
					 *      Author H2zero
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#ifndef MAIN_NIMBLELOG_H_
 | 
				
			||||||
 | 
					#define MAIN_NIMBLELOG_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "nimconfig.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_ENABLED)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(CONFIG_NIMBLE_CPP_IDF) // using esp-idf
 | 
				
			||||||
 | 
					#  include "esp_log.h"
 | 
				
			||||||
 | 
					#  ifndef CONFIG_NIMBLE_CPP_LOG_LEVEL
 | 
				
			||||||
 | 
					#    define CONFIG_NIMBLE_CPP_LOG_LEVEL 0
 | 
				
			||||||
 | 
					#  endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#  define NIMBLE_CPP_LOG_PRINT(level, tag, format, ...) do { \
 | 
				
			||||||
 | 
					    if (CONFIG_NIMBLE_CPP_LOG_LEVEL >= level) \
 | 
				
			||||||
 | 
					      ESP_LOG_LEVEL_LOCAL(level, tag, format, ##__VA_ARGS__); \
 | 
				
			||||||
 | 
					    } while(0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#  define NIMBLE_LOGD(tag, format, ...) \
 | 
				
			||||||
 | 
					     NIMBLE_CPP_LOG_PRINT(ESP_LOG_DEBUG, tag, format, ##__VA_ARGS__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#  define NIMBLE_LOGI(tag, format, ...) \
 | 
				
			||||||
 | 
					     NIMBLE_CPP_LOG_PRINT(ESP_LOG_INFO, tag, format, ##__VA_ARGS__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#  define NIMBLE_LOGW(tag, format, ...) \
 | 
				
			||||||
 | 
					     NIMBLE_CPP_LOG_PRINT(ESP_LOG_WARN, tag, format, ##__VA_ARGS__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#  define NIMBLE_LOGE(tag, format, ...) \
 | 
				
			||||||
 | 
					     NIMBLE_CPP_LOG_PRINT(ESP_LOG_ERROR, tag, format, ##__VA_ARGS__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#  define NIMBLE_LOGC(tag, format, ...) \
 | 
				
			||||||
 | 
					     NIMBLE_CPP_LOG_PRINT(ESP_LOG_ERROR, tag, format, ##__VA_ARGS__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#else // using Arduino
 | 
				
			||||||
 | 
					#  include "nimble/porting/nimble/include/syscfg/syscfg.h"
 | 
				
			||||||
 | 
					#  include "nimble/console/console.h"
 | 
				
			||||||
 | 
					#  ifndef CONFIG_NIMBLE_CPP_LOG_LEVEL
 | 
				
			||||||
 | 
					#    if defined(ARDUINO_ARCH_ESP32) && defined(CORE_DEBUG_LEVEL)
 | 
				
			||||||
 | 
					#      define CONFIG_NIMBLE_CPP_LOG_LEVEL CORE_DEBUG_LEVEL
 | 
				
			||||||
 | 
					#    else
 | 
				
			||||||
 | 
					#      define CONFIG_NIMBLE_CPP_LOG_LEVEL 0
 | 
				
			||||||
 | 
					#    endif
 | 
				
			||||||
 | 
					#  endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#  if CONFIG_NIMBLE_CPP_LOG_LEVEL >= 4
 | 
				
			||||||
 | 
					#    define NIMBLE_LOGD( tag, format, ... ) console_printf("D %s: " format "\n", tag, ##__VA_ARGS__)
 | 
				
			||||||
 | 
					#  else
 | 
				
			||||||
 | 
					#    define NIMBLE_LOGD( tag, format, ... ) (void)tag
 | 
				
			||||||
 | 
					#  endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#  if CONFIG_NIMBLE_CPP_LOG_LEVEL >= 3
 | 
				
			||||||
 | 
					#    define NIMBLE_LOGI( tag, format, ... ) console_printf("I %s: " format "\n", tag, ##__VA_ARGS__)
 | 
				
			||||||
 | 
					#  else
 | 
				
			||||||
 | 
					#    define NIMBLE_LOGI( tag, format, ... ) (void)tag
 | 
				
			||||||
 | 
					#  endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#  if CONFIG_NIMBLE_CPP_LOG_LEVEL >= 2
 | 
				
			||||||
 | 
					#    define NIMBLE_LOGW( tag, format, ... ) console_printf("W %s: " format "\n", tag, ##__VA_ARGS__)
 | 
				
			||||||
 | 
					#  else
 | 
				
			||||||
 | 
					#    define NIMBLE_LOGW( tag, format, ... ) (void)tag
 | 
				
			||||||
 | 
					#  endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#  if CONFIG_NIMBLE_CPP_LOG_LEVEL >= 1
 | 
				
			||||||
 | 
					#    define NIMBLE_LOGE( tag, format, ... ) console_printf("E %s: " format "\n", tag, ##__VA_ARGS__)
 | 
				
			||||||
 | 
					#    define NIMBLE_LOGC( tag, format, ... ) console_printf("CRIT %s: " format "\n", tag, ##__VA_ARGS__)
 | 
				
			||||||
 | 
					#  else
 | 
				
			||||||
 | 
					#    define NIMBLE_LOGE( tag, format, ... ) (void)tag
 | 
				
			||||||
 | 
					#    define NIMBLE_LOGC( tag, format, ... ) (void)tag
 | 
				
			||||||
 | 
					#  endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* CONFIG_NIMBLE_CPP_IDF */
 | 
				
			||||||
 | 
					#endif /* CONFIG_BT_ENABLED */
 | 
				
			||||||
 | 
					#endif /* MAIN_NIMBLELOG_H_ */
 | 
				
			||||||
@@ -0,0 +1,857 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * NimBLERemoteCharacteristic.cpp
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created: on Jan 27 2020
 | 
				
			||||||
 | 
					 *      Author H2zero
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Originally:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * BLERemoteCharacteristic.cpp
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created on: Mar 16, 2017
 | 
				
			||||||
 | 
					 *      Author: kolban
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "nimconfig.h"
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "NimBLERemoteCharacteristic.h"
 | 
				
			||||||
 | 
					#include "NimBLEUtils.h"
 | 
				
			||||||
 | 
					#include "NimBLELog.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <climits>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char* LOG_TAG = "NimBLERemoteCharacteristic";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Constructor.
 | 
				
			||||||
 | 
					 * @param [in] reference to the service this characteristic belongs to.
 | 
				
			||||||
 | 
					 * @param [in] ble_gatt_chr struct defined as:
 | 
				
			||||||
 | 
					 *  struct ble_gatt_chr {
 | 
				
			||||||
 | 
					 *      uint16_t def_handle;
 | 
				
			||||||
 | 
					 *      uint16_t val_handle;
 | 
				
			||||||
 | 
					 *      uint8_t properties;
 | 
				
			||||||
 | 
					 *      ble_uuid_any_t uuid;
 | 
				
			||||||
 | 
					 *  };
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					 NimBLERemoteCharacteristic::NimBLERemoteCharacteristic(NimBLERemoteService *pRemoteService,
 | 
				
			||||||
 | 
					                                                        const struct ble_gatt_chr *chr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, ">> NimBLERemoteCharacteristic()");
 | 
				
			||||||
 | 
					     switch (chr->uuid.u.type) {
 | 
				
			||||||
 | 
					        case BLE_UUID_TYPE_16:
 | 
				
			||||||
 | 
					            m_uuid = NimBLEUUID(chr->uuid.u16.value);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case BLE_UUID_TYPE_32:
 | 
				
			||||||
 | 
					            m_uuid = NimBLEUUID(chr->uuid.u32.value);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case BLE_UUID_TYPE_128:
 | 
				
			||||||
 | 
					            m_uuid = NimBLEUUID(const_cast<ble_uuid128_t*>(&chr->uuid.u128));
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        default:
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    m_handle             = chr->val_handle;
 | 
				
			||||||
 | 
					    m_defHandle          = chr->def_handle;
 | 
				
			||||||
 | 
					    m_endHandle          = 0;
 | 
				
			||||||
 | 
					    m_charProp           = chr->properties;
 | 
				
			||||||
 | 
					    m_pRemoteService     = pRemoteService;
 | 
				
			||||||
 | 
					    m_notifyCallback     = nullptr;
 | 
				
			||||||
 | 
					    m_timestamp          = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, "<< NimBLERemoteCharacteristic(): %s", m_uuid.toString().c_str());
 | 
				
			||||||
 | 
					 } // NimBLERemoteCharacteristic
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 *@brief Destructor.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLERemoteCharacteristic::~NimBLERemoteCharacteristic() {
 | 
				
			||||||
 | 
					    deleteDescriptors();
 | 
				
			||||||
 | 
					} // ~NimBLERemoteCharacteristic
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					#define BLE_GATT_CHR_PROP_BROADCAST                     0x01
 | 
				
			||||||
 | 
					#define BLE_GATT_CHR_PROP_READ                          0x02
 | 
				
			||||||
 | 
					#define BLE_GATT_CHR_PROP_WRITE_NO_RSP                  0x04
 | 
				
			||||||
 | 
					#define BLE_GATT_CHR_PROP_WRITE                         0x08
 | 
				
			||||||
 | 
					#define BLE_GATT_CHR_PROP_NOTIFY                        0x10
 | 
				
			||||||
 | 
					#define BLE_GATT_CHR_PROP_INDICATE                      0x20
 | 
				
			||||||
 | 
					#define BLE_GATT_CHR_PROP_AUTH_SIGN_WRITE               0x40
 | 
				
			||||||
 | 
					#define BLE_GATT_CHR_PROP_EXTENDED                      0x80
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Does the characteristic support broadcasting?
 | 
				
			||||||
 | 
					 * @return True if the characteristic supports broadcasting.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool NimBLERemoteCharacteristic::canBroadcast() {
 | 
				
			||||||
 | 
					    return (m_charProp & BLE_GATT_CHR_PROP_BROADCAST) != 0;
 | 
				
			||||||
 | 
					} // canBroadcast
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Does the characteristic support indications?
 | 
				
			||||||
 | 
					 * @return True if the characteristic supports indications.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool NimBLERemoteCharacteristic::canIndicate() {
 | 
				
			||||||
 | 
					    return (m_charProp & BLE_GATT_CHR_PROP_INDICATE) != 0;
 | 
				
			||||||
 | 
					} // canIndicate
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Does the characteristic support notifications?
 | 
				
			||||||
 | 
					 * @return True if the characteristic supports notifications.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool NimBLERemoteCharacteristic::canNotify() {
 | 
				
			||||||
 | 
					    return (m_charProp & BLE_GATT_CHR_PROP_NOTIFY) != 0;
 | 
				
			||||||
 | 
					} // canNotify
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Does the characteristic support reading?
 | 
				
			||||||
 | 
					 * @return True if the characteristic supports reading.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool NimBLERemoteCharacteristic::canRead() {
 | 
				
			||||||
 | 
					    return (m_charProp & BLE_GATT_CHR_PROP_READ) != 0;
 | 
				
			||||||
 | 
					} // canRead
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Does the characteristic support writing?
 | 
				
			||||||
 | 
					 * @return True if the characteristic supports writing.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool NimBLERemoteCharacteristic::canWrite() {
 | 
				
			||||||
 | 
					    return (m_charProp & BLE_GATT_CHR_PROP_WRITE) != 0;
 | 
				
			||||||
 | 
					} // canWrite
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Does the characteristic support writing with no response?
 | 
				
			||||||
 | 
					 * @return True if the characteristic supports writing with no response.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool NimBLERemoteCharacteristic::canWriteNoResponse() {
 | 
				
			||||||
 | 
					    return (m_charProp & BLE_GATT_CHR_PROP_WRITE_NO_RSP) != 0;
 | 
				
			||||||
 | 
					} // canWriteNoResponse
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Callback used by the API when a descriptor is discovered or search complete.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int NimBLERemoteCharacteristic::descriptorDiscCB(uint16_t conn_handle,
 | 
				
			||||||
 | 
					                                    const struct ble_gatt_error *error,
 | 
				
			||||||
 | 
					                                    uint16_t chr_val_handle,
 | 
				
			||||||
 | 
					                                    const struct ble_gatt_dsc *dsc,
 | 
				
			||||||
 | 
					                                    void *arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int rc = error->status;
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, "Descriptor Discovered >> status: %d handle: %d",
 | 
				
			||||||
 | 
					                         rc, (rc == 0) ? dsc->handle : -1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    desc_filter_t *filter = (desc_filter_t*)arg;
 | 
				
			||||||
 | 
					    const NimBLEUUID *uuid_filter = filter->uuid;
 | 
				
			||||||
 | 
					    ble_task_data_t *pTaskData = (ble_task_data_t*)filter->task_data;
 | 
				
			||||||
 | 
					    NimBLERemoteCharacteristic *characteristic = (NimBLERemoteCharacteristic*)pTaskData->pATT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (characteristic->getRemoteService()->getClient()->getConnId() != conn_handle){
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    switch (rc) {
 | 
				
			||||||
 | 
					        case 0: {
 | 
				
			||||||
 | 
					            if (uuid_filter != nullptr) {
 | 
				
			||||||
 | 
					                if (ble_uuid_cmp(&uuid_filter->getNative()->u, &dsc->uuid.u) != 0) {
 | 
				
			||||||
 | 
					                    return 0;
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    rc = BLE_HS_EDONE;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            NimBLERemoteDescriptor* pNewRemoteDescriptor = new NimBLERemoteDescriptor(characteristic, dsc);
 | 
				
			||||||
 | 
					            characteristic->m_descriptorVector.push_back(pNewRemoteDescriptor);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        default:
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*  If rc == BLE_HS_EDONE, resume the task with a success error code and stop the discovery process.
 | 
				
			||||||
 | 
					     *  Else if rc == 0, just return 0 to continue the discovery until we get BLE_HS_EDONE.
 | 
				
			||||||
 | 
					     *  If we get any other error code tell the application to abort by returning non-zero in the rc.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    if (rc == BLE_HS_EDONE) {
 | 
				
			||||||
 | 
					        pTaskData->rc = 0;
 | 
				
			||||||
 | 
					        xTaskNotifyGive(pTaskData->task);
 | 
				
			||||||
 | 
					    } else if(rc != 0) {
 | 
				
			||||||
 | 
					        // Error; abort discovery.
 | 
				
			||||||
 | 
					        pTaskData->rc = rc;
 | 
				
			||||||
 | 
					        xTaskNotifyGive(pTaskData->task);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG,"<< Descriptor Discovered. status: %d", pTaskData->rc);
 | 
				
			||||||
 | 
					    return rc;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief callback from NimBLE when the next characteristic of the service is discovered.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int NimBLERemoteCharacteristic::nextCharCB(uint16_t conn_handle,
 | 
				
			||||||
 | 
					                                           const struct ble_gatt_error *error,
 | 
				
			||||||
 | 
					                                           const struct ble_gatt_chr *chr, void *arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int rc = error->status;
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, "Next Characteristic >> status: %d handle: %d",
 | 
				
			||||||
 | 
					                         rc, (rc == 0) ? chr->val_handle : -1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ble_task_data_t *pTaskData = (ble_task_data_t*)arg;
 | 
				
			||||||
 | 
					    NimBLERemoteCharacteristic *pChar = (NimBLERemoteCharacteristic*)pTaskData->pATT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (pChar->getRemoteService()->getClient()->getConnId() != conn_handle) {
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (rc == 0) {
 | 
				
			||||||
 | 
					        pChar->m_endHandle = chr->def_handle - 1;
 | 
				
			||||||
 | 
					        rc = BLE_HS_EDONE;
 | 
				
			||||||
 | 
					    } else if (rc == BLE_HS_EDONE) {
 | 
				
			||||||
 | 
					        pChar->m_endHandle = pChar->getRemoteService()->getEndHandle();
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        pTaskData->rc = rc;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    xTaskNotifyGive(pTaskData->task);
 | 
				
			||||||
 | 
					    return rc;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Populate the descriptors (if any) for this characteristic.
 | 
				
			||||||
 | 
					 * @param [in] the end handle of the characteristic, or the service, whichever comes first.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool NimBLERemoteCharacteristic::retrieveDescriptors(const NimBLEUUID *uuid_filter) {
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, ">> retrieveDescriptors() for characteristic: %s", getUUID().toString().c_str());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // If this is the last handle then there are no descriptors
 | 
				
			||||||
 | 
					    if (m_handle == getRemoteService()->getEndHandle()) {
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int rc = 0;
 | 
				
			||||||
 | 
					    TaskHandle_t cur_task = xTaskGetCurrentTaskHandle();
 | 
				
			||||||
 | 
					    ble_task_data_t taskData = {this, cur_task, 0, nullptr};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // If we don't know the end handle of this characteristic retrieve the next one in the service
 | 
				
			||||||
 | 
					    // The end handle is the next characteristic definition handle -1.
 | 
				
			||||||
 | 
					    if (m_endHandle == 0) {
 | 
				
			||||||
 | 
					        rc = ble_gattc_disc_all_chrs(getRemoteService()->getClient()->getConnId(),
 | 
				
			||||||
 | 
					                                     m_handle,
 | 
				
			||||||
 | 
					                                     getRemoteService()->getEndHandle(),
 | 
				
			||||||
 | 
					                                     NimBLERemoteCharacteristic::nextCharCB,
 | 
				
			||||||
 | 
					                                     &taskData);
 | 
				
			||||||
 | 
					        if (rc != 0) {
 | 
				
			||||||
 | 
					            NIMBLE_LOGE(LOG_TAG, "Error getting end handle rc=%d", rc);
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef ulTaskNotifyValueClear
 | 
				
			||||||
 | 
					        // Clear the task notification value to ensure we block
 | 
				
			||||||
 | 
					        ulTaskNotifyValueClear(cur_task, ULONG_MAX);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (taskData.rc != 0) {
 | 
				
			||||||
 | 
					            NIMBLE_LOGE(LOG_TAG, "Could not retrieve end handle rc=%d", taskData.rc);
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    desc_filter_t filter = {uuid_filter, &taskData};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    rc = ble_gattc_disc_all_dscs(getRemoteService()->getClient()->getConnId(),
 | 
				
			||||||
 | 
					                                 m_handle,
 | 
				
			||||||
 | 
					                                 m_endHandle,
 | 
				
			||||||
 | 
					                                 NimBLERemoteCharacteristic::descriptorDiscCB,
 | 
				
			||||||
 | 
					                                 &filter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (rc != 0) {
 | 
				
			||||||
 | 
					        NIMBLE_LOGE(LOG_TAG, "ble_gattc_disc_all_dscs: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef ulTaskNotifyValueClear
 | 
				
			||||||
 | 
					    // Clear the task notification value to ensure we block
 | 
				
			||||||
 | 
					    ulTaskNotifyValueClear(cur_task, ULONG_MAX);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (taskData.rc != 0) {
 | 
				
			||||||
 | 
					        NIMBLE_LOGE(LOG_TAG, "Failed to retrieve descriptors; startHandle:%d endHandle:%d taskData.rc=%d",
 | 
				
			||||||
 | 
					                             m_handle, m_endHandle, taskData.rc);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, "<< retrieveDescriptors(): Found %d descriptors.", m_descriptorVector.size());
 | 
				
			||||||
 | 
					    return (taskData.rc == 0);
 | 
				
			||||||
 | 
					} // retrieveDescriptors
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the descriptor instance with the given UUID that belongs to this characteristic.
 | 
				
			||||||
 | 
					 * @param [in] uuid The UUID of the descriptor to find.
 | 
				
			||||||
 | 
					 * @return The Remote descriptor (if present) or null if not present.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLERemoteDescriptor* NimBLERemoteCharacteristic::getDescriptor(const NimBLEUUID &uuid) {
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, ">> getDescriptor: uuid: %s", uuid.toString().c_str());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for(auto &it: m_descriptorVector) {
 | 
				
			||||||
 | 
					        if(it->getUUID() == uuid) {
 | 
				
			||||||
 | 
					            NIMBLE_LOGD(LOG_TAG, "<< getDescriptor: found the descriptor with uuid: %s", uuid.toString().c_str());
 | 
				
			||||||
 | 
					            return it;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    size_t prev_size = m_descriptorVector.size();
 | 
				
			||||||
 | 
					    if(retrieveDescriptors(&uuid)) {
 | 
				
			||||||
 | 
					        if(m_descriptorVector.size() > prev_size) {
 | 
				
			||||||
 | 
					            return m_descriptorVector.back();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // If the request was successful but 16/32 bit uuid not found
 | 
				
			||||||
 | 
					        // try again with the 128 bit uuid.
 | 
				
			||||||
 | 
					        if(uuid.bitSize() == BLE_UUID_TYPE_16 ||
 | 
				
			||||||
 | 
					           uuid.bitSize() == BLE_UUID_TYPE_32)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            NimBLEUUID uuid128(uuid);
 | 
				
			||||||
 | 
					            uuid128.to128();
 | 
				
			||||||
 | 
					            if(retrieveDescriptors(&uuid128)) {
 | 
				
			||||||
 | 
					                if(m_descriptorVector.size() > prev_size) {
 | 
				
			||||||
 | 
					                    return m_descriptorVector.back();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            // If the request was successful but the 128 bit uuid not found
 | 
				
			||||||
 | 
					            // try again with the 16 bit uuid.
 | 
				
			||||||
 | 
					            NimBLEUUID uuid16(uuid);
 | 
				
			||||||
 | 
					            uuid16.to16();
 | 
				
			||||||
 | 
					            // if the uuid was 128 bit but not of the BLE base type this check will fail
 | 
				
			||||||
 | 
					            if (uuid16.bitSize() == BLE_UUID_TYPE_16) {
 | 
				
			||||||
 | 
					                if(retrieveDescriptors(&uuid16)) {
 | 
				
			||||||
 | 
					                    if(m_descriptorVector.size() > prev_size) {
 | 
				
			||||||
 | 
					                        return m_descriptorVector.back();
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, "<< getDescriptor: Not found");
 | 
				
			||||||
 | 
					    return nullptr;
 | 
				
			||||||
 | 
					} // getDescriptor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get a pointer to the vector of found descriptors.
 | 
				
			||||||
 | 
					 * @param [in] refresh If true the current descriptor vector will be cleared and\n
 | 
				
			||||||
 | 
					 * all descriptors for this characteristic retrieved from the peripheral.\n
 | 
				
			||||||
 | 
					 * If false the vector will be returned with the currently stored descriptors
 | 
				
			||||||
 | 
					 * of this characteristic.
 | 
				
			||||||
 | 
					 * @return A pointer to the vector of descriptors for this characteristic.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					std::vector<NimBLERemoteDescriptor*>* NimBLERemoteCharacteristic::getDescriptors(bool refresh) {
 | 
				
			||||||
 | 
					    if(refresh) {
 | 
				
			||||||
 | 
					        deleteDescriptors();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!retrieveDescriptors()) {
 | 
				
			||||||
 | 
					            NIMBLE_LOGE(LOG_TAG, "Error: Failed to get descriptors");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else{
 | 
				
			||||||
 | 
					            NIMBLE_LOGI(LOG_TAG, "Found %d descriptor(s)", m_descriptorVector.size());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return &m_descriptorVector;
 | 
				
			||||||
 | 
					} // getDescriptors
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get iterator to the beginning of the vector of remote descriptor pointers.
 | 
				
			||||||
 | 
					 * @return An iterator to the beginning of the vector of remote descriptor pointers.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					std::vector<NimBLERemoteDescriptor*>::iterator NimBLERemoteCharacteristic::begin() {
 | 
				
			||||||
 | 
					    return m_descriptorVector.begin();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get iterator to the end of the vector of remote descriptor pointers.
 | 
				
			||||||
 | 
					 * @return An iterator to the end of the vector of remote descriptor pointers.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					std::vector<NimBLERemoteDescriptor*>::iterator NimBLERemoteCharacteristic::end() {
 | 
				
			||||||
 | 
					    return m_descriptorVector.end();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the handle for this characteristic.
 | 
				
			||||||
 | 
					 * @return The handle for this characteristic.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint16_t NimBLERemoteCharacteristic::getHandle() {
 | 
				
			||||||
 | 
					    return m_handle;
 | 
				
			||||||
 | 
					} // getHandle
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the handle for this characteristics definition.
 | 
				
			||||||
 | 
					 * @return The handle for this characteristic definition.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint16_t NimBLERemoteCharacteristic::getDefHandle() {
 | 
				
			||||||
 | 
					    return m_defHandle;
 | 
				
			||||||
 | 
					} // getDefHandle
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the remote service associated with this characteristic.
 | 
				
			||||||
 | 
					 * @return The remote service associated with this characteristic.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLERemoteService* NimBLERemoteCharacteristic::getRemoteService() {
 | 
				
			||||||
 | 
					    return m_pRemoteService;
 | 
				
			||||||
 | 
					} // getRemoteService
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the UUID for this characteristic.
 | 
				
			||||||
 | 
					 * @return The UUID for this characteristic.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEUUID NimBLERemoteCharacteristic::getUUID() {
 | 
				
			||||||
 | 
					    return m_uuid;
 | 
				
			||||||
 | 
					} // getUUID
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the value of the remote characteristic.
 | 
				
			||||||
 | 
					 * @param [in] timestamp A pointer to a time_t struct to store the time the value was read.
 | 
				
			||||||
 | 
					 * @return The value of the remote characteristic.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					std::string NimBLERemoteCharacteristic::getValue(time_t *timestamp) {
 | 
				
			||||||
 | 
					    ble_npl_hw_enter_critical();
 | 
				
			||||||
 | 
					    std::string value = m_value;
 | 
				
			||||||
 | 
					    if(timestamp != nullptr) {
 | 
				
			||||||
 | 
					        *timestamp = m_timestamp;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    ble_npl_hw_exit_critical(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return value;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Read an unsigned 16 bit value
 | 
				
			||||||
 | 
					 * @return The unsigned 16 bit value.
 | 
				
			||||||
 | 
					 * @deprecated Use readValue<uint16_t>().
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint16_t NimBLERemoteCharacteristic::readUInt16() {
 | 
				
			||||||
 | 
					    return readValue<uint16_t>();
 | 
				
			||||||
 | 
					} // readUInt16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Read an unsigned 32 bit value.
 | 
				
			||||||
 | 
					 * @return the unsigned 32 bit value.
 | 
				
			||||||
 | 
					 * @deprecated Use readValue<uint32_t>().
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint32_t NimBLERemoteCharacteristic::readUInt32() {
 | 
				
			||||||
 | 
					    return readValue<uint32_t>();
 | 
				
			||||||
 | 
					} // readUInt32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Read a byte value
 | 
				
			||||||
 | 
					 * @return The value as a byte
 | 
				
			||||||
 | 
					 * @deprecated Use readValue<uint8_t>().
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint8_t NimBLERemoteCharacteristic::readUInt8() {
 | 
				
			||||||
 | 
					    return readValue<uint8_t>();
 | 
				
			||||||
 | 
					} // readUInt8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Read a float value.
 | 
				
			||||||
 | 
					 * @return the float value.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					float NimBLERemoteCharacteristic::readFloat() {
 | 
				
			||||||
 | 
						return readValue<float>();
 | 
				
			||||||
 | 
					} // readFloat
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Read the value of the remote characteristic.
 | 
				
			||||||
 | 
					 * @param [in] timestamp A pointer to a time_t struct to store the time the value was read.
 | 
				
			||||||
 | 
					 * @return The value of the remote characteristic.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					std::string NimBLERemoteCharacteristic::readValue(time_t *timestamp) {
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, ">> readValue(): uuid: %s, handle: %d 0x%.2x",
 | 
				
			||||||
 | 
					                         getUUID().toString().c_str(), getHandle(), getHandle());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NimBLEClient* pClient = getRemoteService()->getClient();
 | 
				
			||||||
 | 
					    std::string value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!pClient->isConnected()) {
 | 
				
			||||||
 | 
					        NIMBLE_LOGE(LOG_TAG, "Disconnected");
 | 
				
			||||||
 | 
					        return value;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int rc = 0;
 | 
				
			||||||
 | 
					    int retryCount = 1;
 | 
				
			||||||
 | 
					    TaskHandle_t cur_task = xTaskGetCurrentTaskHandle();
 | 
				
			||||||
 | 
					    ble_task_data_t taskData = {this, cur_task, 0, &value};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    do {
 | 
				
			||||||
 | 
					        rc = ble_gattc_read_long(pClient->getConnId(), m_handle, 0,
 | 
				
			||||||
 | 
					                                 NimBLERemoteCharacteristic::onReadCB,
 | 
				
			||||||
 | 
					                                 &taskData);
 | 
				
			||||||
 | 
					        if (rc != 0) {
 | 
				
			||||||
 | 
					            NIMBLE_LOGE(LOG_TAG, "Error: Failed to read characteristic; rc=%d, %s",
 | 
				
			||||||
 | 
					                                  rc, NimBLEUtils::returnCodeToString(rc));
 | 
				
			||||||
 | 
					            return value;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef ulTaskNotifyValueClear
 | 
				
			||||||
 | 
					        // Clear the task notification value to ensure we block
 | 
				
			||||||
 | 
					        ulTaskNotifyValueClear(cur_task, ULONG_MAX);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
 | 
				
			||||||
 | 
					        rc = taskData.rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        switch(rc){
 | 
				
			||||||
 | 
					            case 0:
 | 
				
			||||||
 | 
					            case BLE_HS_EDONE:
 | 
				
			||||||
 | 
					                rc = 0;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            // Characteristic is not long-readable, return with what we have.
 | 
				
			||||||
 | 
					            case BLE_HS_ATT_ERR(BLE_ATT_ERR_ATTR_NOT_LONG):
 | 
				
			||||||
 | 
					                NIMBLE_LOGI(LOG_TAG, "Attribute not long");
 | 
				
			||||||
 | 
					                rc = 0;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHEN):
 | 
				
			||||||
 | 
					            case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHOR):
 | 
				
			||||||
 | 
					            case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_ENC):
 | 
				
			||||||
 | 
					                if (retryCount && pClient->secureConnection())
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					            /* Else falls through. */
 | 
				
			||||||
 | 
					            default:
 | 
				
			||||||
 | 
					                NIMBLE_LOGE(LOG_TAG, "<< readValue rc=%d", rc);
 | 
				
			||||||
 | 
					                return value;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    } while(rc != 0 && retryCount--);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    time_t t = time(nullptr);
 | 
				
			||||||
 | 
					    ble_npl_hw_enter_critical();
 | 
				
			||||||
 | 
					    m_value = value;
 | 
				
			||||||
 | 
					    m_timestamp = t;
 | 
				
			||||||
 | 
					    if(timestamp != nullptr) {
 | 
				
			||||||
 | 
					        *timestamp = m_timestamp;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    ble_npl_hw_exit_critical(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, "<< readValue length: %d rc=%d", value.length(), rc);
 | 
				
			||||||
 | 
					    return value;
 | 
				
			||||||
 | 
					} // readValue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Callback for characteristic read operation.
 | 
				
			||||||
 | 
					 * @return success == 0 or error code.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int NimBLERemoteCharacteristic::onReadCB(uint16_t conn_handle,
 | 
				
			||||||
 | 
					                const struct ble_gatt_error *error,
 | 
				
			||||||
 | 
					                struct ble_gatt_attr *attr, void *arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ble_task_data_t *pTaskData = (ble_task_data_t*)arg;
 | 
				
			||||||
 | 
					    NimBLERemoteCharacteristic *characteristic = (NimBLERemoteCharacteristic*)pTaskData->pATT;
 | 
				
			||||||
 | 
					    uint16_t conn_id = characteristic->getRemoteService()->getClient()->getConnId();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(conn_id != conn_handle) {
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NIMBLE_LOGI(LOG_TAG, "Read complete; status=%d conn_handle=%d", error->status, conn_handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::string *strBuf = (std::string*)pTaskData->buf;
 | 
				
			||||||
 | 
					    int rc = error->status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(rc == 0) {
 | 
				
			||||||
 | 
					        if(attr) {
 | 
				
			||||||
 | 
					            uint16_t data_len = OS_MBUF_PKTLEN(attr->om);
 | 
				
			||||||
 | 
					            if(((*strBuf).length() + data_len) > BLE_ATT_ATTR_MAX_LEN) {
 | 
				
			||||||
 | 
					                rc = BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                NIMBLE_LOGD(LOG_TAG, "Got %u bytes", data_len);
 | 
				
			||||||
 | 
					                (*strBuf) += std::string((char*) attr->om->om_data, data_len);
 | 
				
			||||||
 | 
					                return 0;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pTaskData->rc = rc;
 | 
				
			||||||
 | 
					    xTaskNotifyGive(pTaskData->task);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return rc;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Subscribe or unsubscribe for notifications or indications.
 | 
				
			||||||
 | 
					 * @param [in] val 0x00 to unsubscribe, 0x01 for notifications, 0x02 for indications.
 | 
				
			||||||
 | 
					 * @param [in] notifyCallback A callback to be invoked for a notification.
 | 
				
			||||||
 | 
					 * @param [in] response If write response required set this to true.
 | 
				
			||||||
 | 
					 * If NULL is provided then no callback is performed.
 | 
				
			||||||
 | 
					 * @return false if writing to the descriptor failed.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool NimBLERemoteCharacteristic::setNotify(uint16_t val, notify_callback notifyCallback, bool response) {
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, ">> setNotify(): %s, %02x", toString().c_str(), val);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    m_notifyCallback = notifyCallback;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NimBLERemoteDescriptor* desc = getDescriptor(NimBLEUUID((uint16_t)0x2902));
 | 
				
			||||||
 | 
					    if(desc == nullptr) {
 | 
				
			||||||
 | 
					        NIMBLE_LOGW(LOG_TAG, "<< setNotify(): Callback set, CCCD not found");
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, "<< setNotify()");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return desc->writeValue((uint8_t *)&val, 2, response);
 | 
				
			||||||
 | 
					} // setNotify
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Subscribe for notifications or indications.
 | 
				
			||||||
 | 
					 * @param [in] notifications If true, subscribe for notifications, false subscribe for indications.
 | 
				
			||||||
 | 
					 * @param [in] notifyCallback A callback to be invoked for a notification.
 | 
				
			||||||
 | 
					 * @param [in] response If true, require a write response from the descriptor write operation.
 | 
				
			||||||
 | 
					 * If NULL is provided then no callback is performed.
 | 
				
			||||||
 | 
					 * @return false if writing to the descriptor failed.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool NimBLERemoteCharacteristic::subscribe(bool notifications, notify_callback notifyCallback, bool response) {
 | 
				
			||||||
 | 
					    if(notifications) {
 | 
				
			||||||
 | 
					        return setNotify(0x01, notifyCallback, response);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        return setNotify(0x02, notifyCallback, response);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					} // subscribe
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Unsubscribe for notifications or indications.
 | 
				
			||||||
 | 
					 * @param [in] response bool if true, require a write response from the descriptor write operation.
 | 
				
			||||||
 | 
					 * @return false if writing to the descriptor failed.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool NimBLERemoteCharacteristic::unsubscribe(bool response) {
 | 
				
			||||||
 | 
					    return setNotify(0x00, nullptr, response);
 | 
				
			||||||
 | 
					} // unsubscribe
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 /**
 | 
				
			||||||
 | 
					 * @brief backward-compatibility method for subscribe/unsubscribe notifications/indications
 | 
				
			||||||
 | 
					 * @param [in] notifyCallback A callback to be invoked for a notification. If NULL is provided then we
 | 
				
			||||||
 | 
					 * will unregister for notifications.
 | 
				
			||||||
 | 
					 * @param [in] notifications If true, register for notifications, false register for indications.
 | 
				
			||||||
 | 
					 * @param [in] response If true, require a write response from the descriptor write operation.
 | 
				
			||||||
 | 
					 * @return true if successful.
 | 
				
			||||||
 | 
					 * @deprecated Use subscribe() / unsubscribe() instead.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool NimBLERemoteCharacteristic::registerForNotify(notify_callback notifyCallback, bool notifications, bool response) {
 | 
				
			||||||
 | 
					    bool success;
 | 
				
			||||||
 | 
					    if(notifyCallback != nullptr) {
 | 
				
			||||||
 | 
					        success = subscribe(notifications, notifyCallback, response);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        success = unsubscribe(response);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return success;
 | 
				
			||||||
 | 
					} // registerForNotify
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Delete the descriptors in the descriptor vector.
 | 
				
			||||||
 | 
					 * @details We maintain a vector called m_descriptorVector that contains pointers to NimBLERemoteDescriptors
 | 
				
			||||||
 | 
					 * object references. Since we allocated these in this class, we are also responsible for deleting
 | 
				
			||||||
 | 
					 * them. This method does just that.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLERemoteCharacteristic::deleteDescriptors() {
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, ">> deleteDescriptors");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for(auto &it: m_descriptorVector) {
 | 
				
			||||||
 | 
					        delete it;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    m_descriptorVector.clear();
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, "<< deleteDescriptors");
 | 
				
			||||||
 | 
					} // deleteDescriptors
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Delete descriptor by UUID
 | 
				
			||||||
 | 
					 * @param [in] uuid The UUID of the descriptor to be deleted.
 | 
				
			||||||
 | 
					 * @return Number of descriptors left in the vector.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					size_t NimBLERemoteCharacteristic::deleteDescriptor(const NimBLEUUID &uuid) {
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, ">> deleteDescriptor");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for(auto it = m_descriptorVector.begin(); it != m_descriptorVector.end(); ++it) {
 | 
				
			||||||
 | 
					        if((*it)->getUUID() == uuid) {
 | 
				
			||||||
 | 
					            delete *it;
 | 
				
			||||||
 | 
					            m_descriptorVector.erase(it);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, "<< deleteDescriptor");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return m_descriptorVector.size();
 | 
				
			||||||
 | 
					} // deleteDescriptor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Convert a NimBLERemoteCharacteristic to a string representation;
 | 
				
			||||||
 | 
					 * @return a String representation.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					std::string NimBLERemoteCharacteristic::toString() {
 | 
				
			||||||
 | 
					    std::string res = "Characteristic: uuid: " + m_uuid.toString();
 | 
				
			||||||
 | 
					    char val[6];
 | 
				
			||||||
 | 
					    res += ", handle: ";
 | 
				
			||||||
 | 
					    snprintf(val, sizeof(val), "%d", getHandle());
 | 
				
			||||||
 | 
					    res += val;
 | 
				
			||||||
 | 
					    res += " 0x";
 | 
				
			||||||
 | 
					    snprintf(val, sizeof(val), "%04x", getHandle());
 | 
				
			||||||
 | 
					    res += val;
 | 
				
			||||||
 | 
					    res += ", props: ";
 | 
				
			||||||
 | 
					    res += " 0x";
 | 
				
			||||||
 | 
					    snprintf(val, sizeof(val), "%02x", m_charProp);
 | 
				
			||||||
 | 
					    res += val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for(auto &it: m_descriptorVector) {
 | 
				
			||||||
 | 
					        res += "\n" + it->toString();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return res;
 | 
				
			||||||
 | 
					} // toString
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Write the new value for the characteristic.
 | 
				
			||||||
 | 
					 * @param [in] newValue The new value to write.
 | 
				
			||||||
 | 
					 * @param [in] response Do we expect a response?
 | 
				
			||||||
 | 
					 * @return false if not connected or cant perform write for some reason.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool NimBLERemoteCharacteristic::writeValue(const std::string &newValue, bool response) {
 | 
				
			||||||
 | 
					    return writeValue((uint8_t*)newValue.c_str(), newValue.length(), response);
 | 
				
			||||||
 | 
					} // writeValue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Write the new value for the characteristic from a data buffer.
 | 
				
			||||||
 | 
					 * @param [in] data A pointer to a data buffer.
 | 
				
			||||||
 | 
					 * @param [in] length The length of the data in the data buffer.
 | 
				
			||||||
 | 
					 * @param [in] response Whether we require a response from the write.
 | 
				
			||||||
 | 
					 * @return false if not connected or cant perform write for some reason.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool NimBLERemoteCharacteristic::writeValue(const uint8_t* data, size_t length, bool response) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, ">> writeValue(), length: %d", length);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NimBLEClient* pClient = getRemoteService()->getClient();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!pClient->isConnected()) {
 | 
				
			||||||
 | 
					        NIMBLE_LOGE(LOG_TAG, "Disconnected");
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int rc = 0;
 | 
				
			||||||
 | 
					    int retryCount = 1;
 | 
				
			||||||
 | 
					    uint16_t mtu = ble_att_mtu(pClient->getConnId()) - 3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Check if the data length is longer than we can write in one connection event.
 | 
				
			||||||
 | 
					    // If so we must do a long write which requires a response.
 | 
				
			||||||
 | 
					    if(length <= mtu && !response) {
 | 
				
			||||||
 | 
					        rc =  ble_gattc_write_no_rsp_flat(pClient->getConnId(), m_handle, data, length);
 | 
				
			||||||
 | 
					        return (rc==0);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    TaskHandle_t cur_task = xTaskGetCurrentTaskHandle();
 | 
				
			||||||
 | 
					    ble_task_data_t taskData = {this, cur_task, 0, nullptr};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    do {
 | 
				
			||||||
 | 
					        if(length > mtu) {
 | 
				
			||||||
 | 
					            NIMBLE_LOGI(LOG_TAG,"long write %d bytes", length);
 | 
				
			||||||
 | 
					            os_mbuf *om = ble_hs_mbuf_from_flat(data, length);
 | 
				
			||||||
 | 
					            rc = ble_gattc_write_long(pClient->getConnId(), m_handle, 0, om,
 | 
				
			||||||
 | 
					                                      NimBLERemoteCharacteristic::onWriteCB,
 | 
				
			||||||
 | 
					                                      &taskData);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            rc = ble_gattc_write_flat(pClient->getConnId(), m_handle,
 | 
				
			||||||
 | 
					                                      data, length,
 | 
				
			||||||
 | 
					                                      NimBLERemoteCharacteristic::onWriteCB,
 | 
				
			||||||
 | 
					                                      &taskData);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (rc != 0) {
 | 
				
			||||||
 | 
					            NIMBLE_LOGE(LOG_TAG, "Error: Failed to write characteristic; rc=%d", rc);
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef ulTaskNotifyValueClear
 | 
				
			||||||
 | 
					        // Clear the task notification value to ensure we block
 | 
				
			||||||
 | 
					        ulTaskNotifyValueClear(cur_task, ULONG_MAX);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
 | 
				
			||||||
 | 
					        rc = taskData.rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        switch(rc){
 | 
				
			||||||
 | 
					            case 0:
 | 
				
			||||||
 | 
					            case BLE_HS_EDONE:
 | 
				
			||||||
 | 
					                rc = 0;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case BLE_HS_ATT_ERR(BLE_ATT_ERR_ATTR_NOT_LONG):
 | 
				
			||||||
 | 
					                NIMBLE_LOGE(LOG_TAG, "Long write not supported by peer; Truncating length to %d", mtu);
 | 
				
			||||||
 | 
					                retryCount++;
 | 
				
			||||||
 | 
					                length = mtu;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHEN):
 | 
				
			||||||
 | 
					            case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHOR):
 | 
				
			||||||
 | 
					            case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_ENC):
 | 
				
			||||||
 | 
					                if (retryCount && pClient->secureConnection())
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					            /* Else falls through. */
 | 
				
			||||||
 | 
					            default:
 | 
				
			||||||
 | 
					                NIMBLE_LOGE(LOG_TAG, "<< writeValue, rc: %d", rc);
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    } while(rc != 0 && retryCount--);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, "<< writeValue, rc: %d", rc);
 | 
				
			||||||
 | 
					    return (rc == 0);
 | 
				
			||||||
 | 
					} // writeValue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Callback for characteristic write operation.
 | 
				
			||||||
 | 
					 * @return success == 0 or error code.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int NimBLERemoteCharacteristic::onWriteCB(uint16_t conn_handle,
 | 
				
			||||||
 | 
					                const struct ble_gatt_error *error,
 | 
				
			||||||
 | 
					                struct ble_gatt_attr *attr, void *arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ble_task_data_t *pTaskData = (ble_task_data_t*)arg;
 | 
				
			||||||
 | 
					    NimBLERemoteCharacteristic *characteristic = (NimBLERemoteCharacteristic*)pTaskData->pATT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(characteristic->getRemoteService()->getClient()->getConnId() != conn_handle){
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NIMBLE_LOGI(LOG_TAG, "Write complete; status=%d conn_handle=%d", error->status, conn_handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pTaskData->rc = error->status;
 | 
				
			||||||
 | 
					    xTaskNotifyGive(pTaskData->task);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_CENTRAL */
 | 
				
			||||||
@@ -0,0 +1,168 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * NimBLERemoteCharacteristic.h
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created: on Jan 27 2020
 | 
				
			||||||
 | 
					 *      Author H2zero
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Originally:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * BLERemoteCharacteristic.h
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created on: Jul 8, 2017
 | 
				
			||||||
 | 
					 *      Author: kolban
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef COMPONENTS_NIMBLEREMOTECHARACTERISTIC_H_
 | 
				
			||||||
 | 
					#define COMPONENTS_NIMBLEREMOTECHARACTERISTIC_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "nimconfig.h"
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "NimBLERemoteService.h"
 | 
				
			||||||
 | 
					#include "NimBLERemoteDescriptor.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <vector>
 | 
				
			||||||
 | 
					#include <functional>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class NimBLERemoteService;
 | 
				
			||||||
 | 
					class NimBLERemoteDescriptor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef std::function<void (NimBLERemoteCharacteristic* pBLERemoteCharacteristic,
 | 
				
			||||||
 | 
					                                uint8_t* pData, size_t length, bool isNotify)> notify_callback;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					    const NimBLEUUID *uuid;
 | 
				
			||||||
 | 
					    void *task_data;
 | 
				
			||||||
 | 
					} desc_filter_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief A model of a remote %BLE characteristic.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class NimBLERemoteCharacteristic {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    ~NimBLERemoteCharacteristic();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Public member functions
 | 
				
			||||||
 | 
					    bool                                           canBroadcast();
 | 
				
			||||||
 | 
					    bool                                           canIndicate();
 | 
				
			||||||
 | 
					    bool                                           canNotify();
 | 
				
			||||||
 | 
					    bool                                           canRead();
 | 
				
			||||||
 | 
					    bool                                           canWrite();
 | 
				
			||||||
 | 
					    bool                                           canWriteNoResponse();
 | 
				
			||||||
 | 
					    std::vector<NimBLERemoteDescriptor*>::iterator begin();
 | 
				
			||||||
 | 
					    std::vector<NimBLERemoteDescriptor*>::iterator end();
 | 
				
			||||||
 | 
					    NimBLERemoteDescriptor*                        getDescriptor(const NimBLEUUID &uuid);
 | 
				
			||||||
 | 
					    std::vector<NimBLERemoteDescriptor*>*          getDescriptors(bool refresh = false);
 | 
				
			||||||
 | 
					    void                                           deleteDescriptors();
 | 
				
			||||||
 | 
					    size_t                                         deleteDescriptor(const NimBLEUUID &uuid);
 | 
				
			||||||
 | 
					    uint16_t                                       getHandle();
 | 
				
			||||||
 | 
					    uint16_t                                       getDefHandle();
 | 
				
			||||||
 | 
					    NimBLEUUID                                     getUUID();
 | 
				
			||||||
 | 
					    std::string                                    readValue(time_t *timestamp = nullptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief A template to convert the remote characteristic data to <type\>.
 | 
				
			||||||
 | 
					     * @tparam T The type to convert the data to.
 | 
				
			||||||
 | 
					     * @param [in] timestamp A pointer to a time_t struct to store the time the value was read.
 | 
				
			||||||
 | 
					     * @param [in] skipSizeCheck If true it will skip checking if the data size is less than <tt>sizeof(<type\>)</tt>.
 | 
				
			||||||
 | 
					     * @return The data converted to <type\> or NULL if skipSizeCheck is false and the data is
 | 
				
			||||||
 | 
					     * less than <tt>sizeof(<type\>)</tt>.
 | 
				
			||||||
 | 
					     * @details <b>Use:</b> <tt>readValue<type>(×tamp, skipSizeCheck);</tt>
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    template<typename T>
 | 
				
			||||||
 | 
					    T                                              readValue(time_t *timestamp = nullptr, bool skipSizeCheck = false) {
 | 
				
			||||||
 | 
					        std::string value = readValue(timestamp);
 | 
				
			||||||
 | 
					        if(!skipSizeCheck && value.size() < sizeof(T)) return T();
 | 
				
			||||||
 | 
					        const char *pData = value.data();
 | 
				
			||||||
 | 
					        return *((T *)pData);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint8_t                                        readUInt8()  __attribute__ ((deprecated("Use template readValue<uint8_t>()")));
 | 
				
			||||||
 | 
					    uint16_t                                       readUInt16() __attribute__ ((deprecated("Use template readValue<uint16_t>()")));
 | 
				
			||||||
 | 
					    uint32_t                                       readUInt32() __attribute__ ((deprecated("Use template readValue<uint32_t>()")));
 | 
				
			||||||
 | 
					    float                                          readFloat()  __attribute__ ((deprecated("Use template readValue<float>()")));
 | 
				
			||||||
 | 
					    std::string                                    getValue(time_t *timestamp = nullptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief A template to convert the remote characteristic data to <type\>.
 | 
				
			||||||
 | 
					     * @tparam T The type to convert the data to.
 | 
				
			||||||
 | 
					     * @param [in] timestamp A pointer to a time_t struct to store the time the value was read.
 | 
				
			||||||
 | 
					     * @param [in] skipSizeCheck If true it will skip checking if the data size is less than <tt>sizeof(<type\>)</tt>.
 | 
				
			||||||
 | 
					     * @return The data converted to <type\> or NULL if skipSizeCheck is false and the data is
 | 
				
			||||||
 | 
					     * less than <tt>sizeof(<type\>)</tt>.
 | 
				
			||||||
 | 
					     * @details <b>Use:</b> <tt>getValue<type>(×tamp, skipSizeCheck);</tt>
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    template<typename T>
 | 
				
			||||||
 | 
					    T                                              getValue(time_t *timestamp = nullptr, bool skipSizeCheck = false) {
 | 
				
			||||||
 | 
					        std::string value = getValue(timestamp);
 | 
				
			||||||
 | 
					        if(!skipSizeCheck && value.size() < sizeof(T)) return T();
 | 
				
			||||||
 | 
					        const char *pData = value.data();
 | 
				
			||||||
 | 
					        return *((T *)pData);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool                                           subscribe(bool notifications = true,
 | 
				
			||||||
 | 
					                                                             notify_callback notifyCallback = nullptr,
 | 
				
			||||||
 | 
					                                                             bool response = false);
 | 
				
			||||||
 | 
					    bool                                           unsubscribe(bool response = false);
 | 
				
			||||||
 | 
					    bool                                           registerForNotify(notify_callback notifyCallback,
 | 
				
			||||||
 | 
					                                                                     bool notifications = true,
 | 
				
			||||||
 | 
					                                                                     bool response = true)
 | 
				
			||||||
 | 
					                                                                     __attribute__ ((deprecated("Use subscribe()/unsubscribe()")));
 | 
				
			||||||
 | 
					    bool                                           writeValue(const uint8_t* data,
 | 
				
			||||||
 | 
					                                                              size_t length,
 | 
				
			||||||
 | 
					                                                              bool response = false);
 | 
				
			||||||
 | 
					    bool                                           writeValue(const std::string &newValue,
 | 
				
			||||||
 | 
					                                                              bool response = false);
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Convenience template to set the remote characteristic value to <type\>val.
 | 
				
			||||||
 | 
					     * @param [in] s The value to write.
 | 
				
			||||||
 | 
					     * @param [in] response True == request write response.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    template<typename T>
 | 
				
			||||||
 | 
					    bool writeValue(const T &s, bool response = false) {
 | 
				
			||||||
 | 
					        return writeValue((uint8_t*)&s, sizeof(T), response);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::string                                    toString();
 | 
				
			||||||
 | 
					    NimBLERemoteService*                           getRemoteService();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NimBLERemoteCharacteristic(NimBLERemoteService *pRemoteservice, const struct ble_gatt_chr *chr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    friend class      NimBLEClient;
 | 
				
			||||||
 | 
					    friend class      NimBLERemoteService;
 | 
				
			||||||
 | 
					    friend class      NimBLERemoteDescriptor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Private member functions
 | 
				
			||||||
 | 
					    bool              setNotify(uint16_t val, notify_callback notifyCallback = nullptr, bool response = true);
 | 
				
			||||||
 | 
					    bool              retrieveDescriptors(const NimBLEUUID *uuid_filter = nullptr);
 | 
				
			||||||
 | 
					    static int        onReadCB(uint16_t conn_handle, const struct ble_gatt_error *error,
 | 
				
			||||||
 | 
					                               struct ble_gatt_attr *attr, void *arg);
 | 
				
			||||||
 | 
					    static int        onWriteCB(uint16_t conn_handle, const struct ble_gatt_error *error,
 | 
				
			||||||
 | 
					                                struct ble_gatt_attr *attr, void *arg);
 | 
				
			||||||
 | 
					    static int        descriptorDiscCB(uint16_t conn_handle, const struct ble_gatt_error *error,
 | 
				
			||||||
 | 
					                                       uint16_t chr_val_handle, const struct ble_gatt_dsc *dsc,
 | 
				
			||||||
 | 
					                                       void *arg);
 | 
				
			||||||
 | 
					    static int        nextCharCB(uint16_t conn_handle, const struct ble_gatt_error *error,
 | 
				
			||||||
 | 
					                                 const struct ble_gatt_chr *chr, void *arg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Private properties
 | 
				
			||||||
 | 
					    NimBLEUUID              m_uuid;
 | 
				
			||||||
 | 
					    uint8_t                 m_charProp;
 | 
				
			||||||
 | 
					    uint16_t                m_handle;
 | 
				
			||||||
 | 
					    uint16_t                m_defHandle;
 | 
				
			||||||
 | 
					    uint16_t                m_endHandle;
 | 
				
			||||||
 | 
					    NimBLERemoteService*    m_pRemoteService;
 | 
				
			||||||
 | 
					    std::string             m_value;
 | 
				
			||||||
 | 
					    notify_callback         m_notifyCallback;
 | 
				
			||||||
 | 
					    time_t                  m_timestamp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // We maintain a vector of descriptors owned by this characteristic.
 | 
				
			||||||
 | 
					    std::vector<NimBLERemoteDescriptor*> m_descriptorVector;
 | 
				
			||||||
 | 
					}; // NimBLERemoteCharacteristic
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_CENTRAL */
 | 
				
			||||||
 | 
					#endif /* COMPONENTS_NIMBLEREMOTECHARACTERISTIC_H_ */
 | 
				
			||||||
@@ -0,0 +1,365 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * NimBLERemoteDescriptor.cpp
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created: on Jan 27 2020
 | 
				
			||||||
 | 
					 *      Author H2zero
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Originally:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * BLERemoteDescriptor.cpp
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created on: Jul 8, 2017
 | 
				
			||||||
 | 
					 *      Author: kolban
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "nimconfig.h"
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "NimBLERemoteDescriptor.h"
 | 
				
			||||||
 | 
					#include "NimBLEUtils.h"
 | 
				
			||||||
 | 
					#include "NimBLELog.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <climits>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char* LOG_TAG = "NimBLERemoteDescriptor";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Remote descriptor constructor.
 | 
				
			||||||
 | 
					 * @param [in] pRemoteCharacteristic A pointer to the Characteristic that this belongs to.
 | 
				
			||||||
 | 
					 * @param [in] dsc A pointer to the struct that contains the descriptor information.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLERemoteDescriptor::NimBLERemoteDescriptor(NimBLERemoteCharacteristic* pRemoteCharacteristic,
 | 
				
			||||||
 | 
					                                               const struct ble_gatt_dsc *dsc)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, ">> NimBLERemoteDescriptor()");
 | 
				
			||||||
 | 
					    switch (dsc->uuid.u.type) {
 | 
				
			||||||
 | 
					        case BLE_UUID_TYPE_16:
 | 
				
			||||||
 | 
					            m_uuid = NimBLEUUID(dsc->uuid.u16.value);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case BLE_UUID_TYPE_32:
 | 
				
			||||||
 | 
					            m_uuid = NimBLEUUID(dsc->uuid.u32.value);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case BLE_UUID_TYPE_128:
 | 
				
			||||||
 | 
					            m_uuid = NimBLEUUID(const_cast<ble_uuid128_t*>(&dsc->uuid.u128));
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        default:
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    m_handle                = dsc->handle;
 | 
				
			||||||
 | 
					    m_pRemoteCharacteristic = pRemoteCharacteristic;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, "<< NimBLERemoteDescriptor(): %s", m_uuid.toString().c_str());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Retrieve the handle associated with this remote descriptor.
 | 
				
			||||||
 | 
					 * @return The handle associated with this remote descriptor.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint16_t NimBLERemoteDescriptor::getHandle() {
 | 
				
			||||||
 | 
					    return m_handle;
 | 
				
			||||||
 | 
					} // getHandle
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the characteristic that owns this descriptor.
 | 
				
			||||||
 | 
					 * @return The characteristic that owns this descriptor.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLERemoteCharacteristic* NimBLERemoteDescriptor::getRemoteCharacteristic() {
 | 
				
			||||||
 | 
					    return m_pRemoteCharacteristic;
 | 
				
			||||||
 | 
					} // getRemoteCharacteristic
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Retrieve the UUID associated this remote descriptor.
 | 
				
			||||||
 | 
					 * @return The UUID associated this remote descriptor.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEUUID NimBLERemoteDescriptor::getUUID() {
 | 
				
			||||||
 | 
					    return m_uuid;
 | 
				
			||||||
 | 
					} // getUUID
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Read a byte value
 | 
				
			||||||
 | 
					 * @return The value as a byte
 | 
				
			||||||
 | 
					 * @deprecated Use readValue<uint8_t>().
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint8_t NimBLERemoteDescriptor::readUInt8() {
 | 
				
			||||||
 | 
					    std::string value = readValue();
 | 
				
			||||||
 | 
					    if (value.length() >= 1) {
 | 
				
			||||||
 | 
					        return (uint8_t) value[0];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					} // readUInt8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Read an unsigned 16 bit value
 | 
				
			||||||
 | 
					 * @return The unsigned 16 bit value.
 | 
				
			||||||
 | 
					 * @deprecated Use readValue<uint16_t>().
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint16_t NimBLERemoteDescriptor::readUInt16() {
 | 
				
			||||||
 | 
					    std::string value = readValue();
 | 
				
			||||||
 | 
					    if (value.length() >= 2) {
 | 
				
			||||||
 | 
					        return *(uint16_t*) value.data();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					} // readUInt16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Read an unsigned 32 bit value.
 | 
				
			||||||
 | 
					 * @return the unsigned 32 bit value.
 | 
				
			||||||
 | 
					 * @deprecated Use readValue<uint32_t>().
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint32_t NimBLERemoteDescriptor::readUInt32() {
 | 
				
			||||||
 | 
					    std::string value = readValue();
 | 
				
			||||||
 | 
					    if (value.length() >= 4) {
 | 
				
			||||||
 | 
					        return *(uint32_t*) value.data();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					} // readUInt32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Read the value of the remote descriptor.
 | 
				
			||||||
 | 
					 * @return The value of the remote descriptor.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					std::string NimBLERemoteDescriptor::readValue() {
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, ">> Descriptor readValue: %s", toString().c_str());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NimBLEClient* pClient = getRemoteCharacteristic()->getRemoteService()->getClient();
 | 
				
			||||||
 | 
					    std::string value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!pClient->isConnected()) {
 | 
				
			||||||
 | 
					        NIMBLE_LOGE(LOG_TAG, "Disconnected");
 | 
				
			||||||
 | 
					        return value;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int rc = 0;
 | 
				
			||||||
 | 
					    int retryCount = 1;
 | 
				
			||||||
 | 
					    TaskHandle_t cur_task = xTaskGetCurrentTaskHandle();
 | 
				
			||||||
 | 
					    ble_task_data_t taskData = {this, cur_task, 0, &value};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    do {
 | 
				
			||||||
 | 
					        rc = ble_gattc_read_long(pClient->getConnId(), m_handle, 0,
 | 
				
			||||||
 | 
					                                 NimBLERemoteDescriptor::onReadCB,
 | 
				
			||||||
 | 
					                                 &taskData);
 | 
				
			||||||
 | 
					        if (rc != 0) {
 | 
				
			||||||
 | 
					            NIMBLE_LOGE(LOG_TAG, "Error: Failed to read descriptor; rc=%d, %s",
 | 
				
			||||||
 | 
					                                  rc, NimBLEUtils::returnCodeToString(rc));
 | 
				
			||||||
 | 
					            return value;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef ulTaskNotifyValueClear
 | 
				
			||||||
 | 
					        // Clear the task notification value to ensure we block
 | 
				
			||||||
 | 
					        ulTaskNotifyValueClear(cur_task, ULONG_MAX);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
 | 
				
			||||||
 | 
					        rc = taskData.rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        switch(rc){
 | 
				
			||||||
 | 
					            case 0:
 | 
				
			||||||
 | 
					            case BLE_HS_EDONE:
 | 
				
			||||||
 | 
					                rc = 0;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            // Descriptor is not long-readable, return with what we have.
 | 
				
			||||||
 | 
					            case BLE_HS_ATT_ERR(BLE_ATT_ERR_ATTR_NOT_LONG):
 | 
				
			||||||
 | 
					                NIMBLE_LOGI(LOG_TAG, "Attribute not long");
 | 
				
			||||||
 | 
					                rc = 0;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHEN):
 | 
				
			||||||
 | 
					            case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHOR):
 | 
				
			||||||
 | 
					            case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_ENC):
 | 
				
			||||||
 | 
					                if (retryCount && pClient->secureConnection())
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					            /* Else falls through. */
 | 
				
			||||||
 | 
					            default:
 | 
				
			||||||
 | 
					                return value;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    } while(rc != 0 && retryCount--);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, "<< Descriptor readValue(): length: %u rc=%d", value.length(), rc);
 | 
				
			||||||
 | 
					    return value;
 | 
				
			||||||
 | 
					} // readValue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Callback for Descriptor read operation.
 | 
				
			||||||
 | 
					 * @return success == 0 or error code.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int NimBLERemoteDescriptor::onReadCB(uint16_t conn_handle,
 | 
				
			||||||
 | 
					                const struct ble_gatt_error *error,
 | 
				
			||||||
 | 
					                struct ble_gatt_attr *attr, void *arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    (void)attr;
 | 
				
			||||||
 | 
					    ble_task_data_t *pTaskData = (ble_task_data_t*)arg;
 | 
				
			||||||
 | 
					    NimBLERemoteDescriptor* desc = (NimBLERemoteDescriptor*)pTaskData->pATT;
 | 
				
			||||||
 | 
					    uint16_t conn_id = desc->getRemoteCharacteristic()->getRemoteService()->getClient()->getConnId();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(conn_id != conn_handle){
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, "Read complete; status=%d conn_handle=%d", error->status, conn_handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::string *strBuf = (std::string*)pTaskData->buf;
 | 
				
			||||||
 | 
					    int rc = error->status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(rc == 0) {
 | 
				
			||||||
 | 
					        if(attr) {
 | 
				
			||||||
 | 
					            uint16_t data_len = OS_MBUF_PKTLEN(attr->om);
 | 
				
			||||||
 | 
					            if(((*strBuf).length() + data_len) > BLE_ATT_ATTR_MAX_LEN) {
 | 
				
			||||||
 | 
					                rc = BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                NIMBLE_LOGD(LOG_TAG, "Got %u bytes", data_len);
 | 
				
			||||||
 | 
					                (*strBuf) += std::string((char*) attr->om->om_data, data_len);
 | 
				
			||||||
 | 
					                return 0;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pTaskData->rc = rc;
 | 
				
			||||||
 | 
					    xTaskNotifyGive(pTaskData->task);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return rc;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Return a string representation of this Remote Descriptor.
 | 
				
			||||||
 | 
					 * @return A string representation of this Remote Descriptor.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					std::string NimBLERemoteDescriptor::toString() {
 | 
				
			||||||
 | 
					    std::string res = "Descriptor: uuid: " + getUUID().toString();
 | 
				
			||||||
 | 
					    char val[6];
 | 
				
			||||||
 | 
					    res += ", handle: ";
 | 
				
			||||||
 | 
					    snprintf(val, sizeof(val), "%d", getHandle());
 | 
				
			||||||
 | 
					    res += val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return res;
 | 
				
			||||||
 | 
					} // toString
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Callback for descriptor write operation.
 | 
				
			||||||
 | 
					 * @return success == 0 or error code.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int NimBLERemoteDescriptor::onWriteCB(uint16_t conn_handle,
 | 
				
			||||||
 | 
					                const struct ble_gatt_error *error,
 | 
				
			||||||
 | 
					                struct ble_gatt_attr *attr, void *arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ble_task_data_t *pTaskData = (ble_task_data_t*)arg;
 | 
				
			||||||
 | 
					    NimBLERemoteDescriptor* descriptor = (NimBLERemoteDescriptor*)pTaskData->pATT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(descriptor->getRemoteCharacteristic()->getRemoteService()->getClient()->getConnId() != conn_handle){
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NIMBLE_LOGI(LOG_TAG, "Write complete; status=%d conn_handle=%d", error->status, conn_handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pTaskData->rc = error->status;
 | 
				
			||||||
 | 
					    xTaskNotifyGive(pTaskData->task);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Write data to the BLE Remote Descriptor.
 | 
				
			||||||
 | 
					 * @param [in] data The data to send to the remote descriptor.
 | 
				
			||||||
 | 
					 * @param [in] length The length of the data to send.
 | 
				
			||||||
 | 
					 * @param [in] response True if we expect a write response.
 | 
				
			||||||
 | 
					 * @return True if successful
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool NimBLERemoteDescriptor::writeValue(const uint8_t* data, size_t length, bool response) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, ">> Descriptor writeValue: %s", toString().c_str());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NimBLEClient* pClient = getRemoteCharacteristic()->getRemoteService()->getClient();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Check to see that we are connected.
 | 
				
			||||||
 | 
					    if (!pClient->isConnected()) {
 | 
				
			||||||
 | 
					        NIMBLE_LOGE(LOG_TAG, "Disconnected");
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int rc = 0;
 | 
				
			||||||
 | 
					    int retryCount = 1;
 | 
				
			||||||
 | 
					    uint16_t mtu = ble_att_mtu(pClient->getConnId()) - 3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Check if the data length is longer than we can write in 1 connection event.
 | 
				
			||||||
 | 
					    // If so we must do a long write which requires a response.
 | 
				
			||||||
 | 
					    if(length <= mtu && !response) {
 | 
				
			||||||
 | 
					        rc =  ble_gattc_write_no_rsp_flat(pClient->getConnId(), m_handle, data, length);
 | 
				
			||||||
 | 
					        return (rc == 0);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    TaskHandle_t cur_task = xTaskGetCurrentTaskHandle();
 | 
				
			||||||
 | 
					    ble_task_data_t taskData = {this, cur_task, 0, nullptr};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    do {
 | 
				
			||||||
 | 
					        if(length > mtu) {
 | 
				
			||||||
 | 
					            NIMBLE_LOGI(LOG_TAG,"long write %d bytes", length);
 | 
				
			||||||
 | 
					            os_mbuf *om = ble_hs_mbuf_from_flat(data, length);
 | 
				
			||||||
 | 
					            rc = ble_gattc_write_long(pClient->getConnId(), m_handle, 0, om,
 | 
				
			||||||
 | 
					                                      NimBLERemoteDescriptor::onWriteCB,
 | 
				
			||||||
 | 
					                                      &taskData);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            rc = ble_gattc_write_flat(pClient->getConnId(), m_handle,
 | 
				
			||||||
 | 
					                                      data, length,
 | 
				
			||||||
 | 
					                                      NimBLERemoteDescriptor::onWriteCB,
 | 
				
			||||||
 | 
					                                      &taskData);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (rc != 0) {
 | 
				
			||||||
 | 
					            NIMBLE_LOGE(LOG_TAG, "Error: Failed to write descriptor; rc=%d", rc);
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef ulTaskNotifyValueClear
 | 
				
			||||||
 | 
					        // Clear the task notification value to ensure we block
 | 
				
			||||||
 | 
					        ulTaskNotifyValueClear(cur_task, ULONG_MAX);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
 | 
				
			||||||
 | 
					        rc = taskData.rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        switch(rc) {
 | 
				
			||||||
 | 
					            case 0:
 | 
				
			||||||
 | 
					            case BLE_HS_EDONE:
 | 
				
			||||||
 | 
					                rc = 0;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case BLE_HS_ATT_ERR(BLE_ATT_ERR_ATTR_NOT_LONG):
 | 
				
			||||||
 | 
					                NIMBLE_LOGE(LOG_TAG, "Long write not supported by peer; Truncating length to %d", mtu);
 | 
				
			||||||
 | 
					                retryCount++;
 | 
				
			||||||
 | 
					                length = mtu;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHEN):
 | 
				
			||||||
 | 
					            case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHOR):
 | 
				
			||||||
 | 
					            case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_ENC):
 | 
				
			||||||
 | 
					                if (retryCount && pClient->secureConnection())
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					            /* Else falls through. */
 | 
				
			||||||
 | 
					            default:
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    } while(rc != 0 && retryCount--);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, "<< Descriptor writeValue, rc: %d",rc);
 | 
				
			||||||
 | 
					    return (rc == 0);
 | 
				
			||||||
 | 
					} // writeValue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Write data represented as a string to the BLE Remote Descriptor.
 | 
				
			||||||
 | 
					 * @param [in] newValue The data to send to the remote descriptor.
 | 
				
			||||||
 | 
					 * @param [in] response True if we expect a response.
 | 
				
			||||||
 | 
					 * @return True if successful
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool NimBLERemoteDescriptor::writeValue(const std::string &newValue, bool response) {
 | 
				
			||||||
 | 
					    return writeValue((uint8_t*) newValue.data(), newValue.length(), response);
 | 
				
			||||||
 | 
					} // writeValue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_CENTRAL */
 | 
				
			||||||
@@ -0,0 +1,83 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * NimBLERemoteDescriptor.h
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created: on Jan 27 2020
 | 
				
			||||||
 | 
					 *      Author H2zero
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Originally:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * BLERemoteDescriptor.h
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created on: Jul 8, 2017
 | 
				
			||||||
 | 
					 *      Author: kolban
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef COMPONENTS_NIMBLEREMOTEDESCRIPTOR_H_
 | 
				
			||||||
 | 
					#define COMPONENTS_NIMBLEREMOTEDESCRIPTOR_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "nimconfig.h"
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "NimBLERemoteCharacteristic.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class NimBLERemoteCharacteristic;
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief A model of remote %BLE descriptor.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class NimBLERemoteDescriptor {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    uint16_t                    getHandle();
 | 
				
			||||||
 | 
					    NimBLERemoteCharacteristic* getRemoteCharacteristic();
 | 
				
			||||||
 | 
					    NimBLEUUID                  getUUID();
 | 
				
			||||||
 | 
					    std::string                 readValue();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief A template to convert the remote descriptor data to <type\>.
 | 
				
			||||||
 | 
					     * @tparam T The type to convert the data to.
 | 
				
			||||||
 | 
					     * @param [in] skipSizeCheck If true it will skip checking if the data size is less than <tt>sizeof(<type\>)</tt>.
 | 
				
			||||||
 | 
					     * @return The data converted to <type\> or NULL if skipSizeCheck is false and the data is
 | 
				
			||||||
 | 
					     * less than <tt>sizeof(<type\>)</tt>.
 | 
				
			||||||
 | 
					     * @details <b>Use:</b> <tt>readValue<type>(skipSizeCheck);</tt>
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    template<typename T>
 | 
				
			||||||
 | 
					    T                           readValue(bool skipSizeCheck = false) {
 | 
				
			||||||
 | 
					        std::string value = readValue();
 | 
				
			||||||
 | 
					        if(!skipSizeCheck && value.size() < sizeof(T)) return T();
 | 
				
			||||||
 | 
					        const char *pData = value.data();
 | 
				
			||||||
 | 
					        return *((T *)pData);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint8_t                     readUInt8()  __attribute__ ((deprecated("Use template readValue<uint8_t>()")));
 | 
				
			||||||
 | 
					    uint16_t                    readUInt16() __attribute__ ((deprecated("Use template readValue<uint16_t>()")));
 | 
				
			||||||
 | 
					    uint32_t                    readUInt32() __attribute__ ((deprecated("Use template readValue<uint32_t>()")));
 | 
				
			||||||
 | 
					    std::string                 toString(void);
 | 
				
			||||||
 | 
					    bool                        writeValue(const uint8_t* data, size_t length, bool response = false);
 | 
				
			||||||
 | 
					    bool                        writeValue(const std::string &newValue, bool response = false);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Convenience template to set the remote descriptor value to <type\>val.
 | 
				
			||||||
 | 
					     * @param [in] s The value to write.
 | 
				
			||||||
 | 
					     * @param [in] response True == request write response.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    template<typename T>
 | 
				
			||||||
 | 
					    bool writeValue(const T &s, bool response = false) {
 | 
				
			||||||
 | 
					        return writeValue((uint8_t*)&s, sizeof(T), response);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    friend class                NimBLERemoteCharacteristic;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NimBLERemoteDescriptor      (NimBLERemoteCharacteristic* pRemoteCharacteristic,
 | 
				
			||||||
 | 
					                                const struct ble_gatt_dsc *dsc);
 | 
				
			||||||
 | 
					    static int                  onWriteCB(uint16_t conn_handle, const struct ble_gatt_error *error,
 | 
				
			||||||
 | 
					                                          struct ble_gatt_attr *attr, void *arg);
 | 
				
			||||||
 | 
					    static int                  onReadCB(uint16_t conn_handle, const struct ble_gatt_error *error,
 | 
				
			||||||
 | 
					                                         struct ble_gatt_attr *attr, void *arg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint16_t                    m_handle;
 | 
				
			||||||
 | 
					    NimBLEUUID                  m_uuid;
 | 
				
			||||||
 | 
					    NimBLERemoteCharacteristic* m_pRemoteCharacteristic;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_CENTRAL */
 | 
				
			||||||
 | 
					#endif /* COMPONENTS_NIMBLEREMOTEDESCRIPTOR_H_ */
 | 
				
			||||||
							
								
								
									
										411
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLERemoteService.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										411
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLERemoteService.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,411 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * NimBLERemoteService.cpp
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created: on Jan 27 2020
 | 
				
			||||||
 | 
					 *      Author H2zero
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Originally:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * BLERemoteService.cpp
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created on: Jul 8, 2017
 | 
				
			||||||
 | 
					 *      Author: kolban
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "nimconfig.h"
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "NimBLERemoteService.h"
 | 
				
			||||||
 | 
					#include "NimBLEUtils.h"
 | 
				
			||||||
 | 
					#include "NimBLEDevice.h"
 | 
				
			||||||
 | 
					#include "NimBLELog.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <climits>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char* LOG_TAG = "NimBLERemoteService";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Remote Service constructor.
 | 
				
			||||||
 | 
					 * @param [in] pClient A pointer to the client this belongs to.
 | 
				
			||||||
 | 
					 * @param [in] service A pointer to the structure with the service information.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLERemoteService::NimBLERemoteService(NimBLEClient* pClient, const struct ble_gatt_svc* service) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, ">> NimBLERemoteService()");
 | 
				
			||||||
 | 
					    m_pClient = pClient;
 | 
				
			||||||
 | 
					    switch (service->uuid.u.type) {
 | 
				
			||||||
 | 
					        case BLE_UUID_TYPE_16:
 | 
				
			||||||
 | 
					            m_uuid = NimBLEUUID(service->uuid.u16.value);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case BLE_UUID_TYPE_32:
 | 
				
			||||||
 | 
					            m_uuid = NimBLEUUID(service->uuid.u32.value);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case BLE_UUID_TYPE_128:
 | 
				
			||||||
 | 
					            m_uuid = NimBLEUUID(const_cast<ble_uuid128_t*>(&service->uuid.u128));
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        default:
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    m_startHandle = service->start_handle;
 | 
				
			||||||
 | 
					    m_endHandle = service->end_handle;
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, "<< NimBLERemoteService(): %s", m_uuid.toString().c_str());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief When deleting the service make sure we delete all characteristics and descriptors.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLERemoteService::~NimBLERemoteService() {
 | 
				
			||||||
 | 
					    deleteCharacteristics();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get iterator to the beginning of the vector of remote characteristic pointers.
 | 
				
			||||||
 | 
					 * @return An iterator to the beginning of the vector of remote characteristic pointers.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					std::vector<NimBLERemoteCharacteristic*>::iterator NimBLERemoteService::begin() {
 | 
				
			||||||
 | 
					    return m_characteristicVector.begin();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get iterator to the end of the vector of remote characteristic pointers.
 | 
				
			||||||
 | 
					 * @return An iterator to the end of the vector of remote characteristic pointers.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					std::vector<NimBLERemoteCharacteristic*>::iterator NimBLERemoteService::end() {
 | 
				
			||||||
 | 
					    return m_characteristicVector.end();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the remote characteristic object for the characteristic UUID.
 | 
				
			||||||
 | 
					 * @param [in] uuid Remote characteristic uuid.
 | 
				
			||||||
 | 
					 * @return A pointer to the remote characteristic object.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLERemoteCharacteristic* NimBLERemoteService::getCharacteristic(const char* uuid) {
 | 
				
			||||||
 | 
					    return getCharacteristic(NimBLEUUID(uuid));
 | 
				
			||||||
 | 
					} // getCharacteristic
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the characteristic object for the UUID.
 | 
				
			||||||
 | 
					 * @param [in] uuid Characteristic uuid.
 | 
				
			||||||
 | 
					 * @return A pointer to the characteristic object, or nullptr if not found.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLERemoteCharacteristic* NimBLERemoteService::getCharacteristic(const NimBLEUUID &uuid) {
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, ">> getCharacteristic: uuid: %s", uuid.toString().c_str());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for(auto &it: m_characteristicVector) {
 | 
				
			||||||
 | 
					        if(it->getUUID() == uuid) {
 | 
				
			||||||
 | 
					            NIMBLE_LOGD(LOG_TAG, "<< getCharacteristic: found the characteristic with uuid: %s", uuid.toString().c_str());
 | 
				
			||||||
 | 
					            return it;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    size_t prev_size = m_characteristicVector.size();
 | 
				
			||||||
 | 
					    if(retrieveCharacteristics(&uuid)) {
 | 
				
			||||||
 | 
					        if(m_characteristicVector.size() > prev_size) {
 | 
				
			||||||
 | 
					            return m_characteristicVector.back();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // If the request was successful but 16/32 bit uuid not found
 | 
				
			||||||
 | 
					        // try again with the 128 bit uuid.
 | 
				
			||||||
 | 
					        if(uuid.bitSize() == BLE_UUID_TYPE_16 ||
 | 
				
			||||||
 | 
					           uuid.bitSize() == BLE_UUID_TYPE_32)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            NimBLEUUID uuid128(uuid);
 | 
				
			||||||
 | 
					            uuid128.to128();
 | 
				
			||||||
 | 
					            if (retrieveCharacteristics(&uuid128)) {
 | 
				
			||||||
 | 
					                if(m_characteristicVector.size() > prev_size) {
 | 
				
			||||||
 | 
					                    return m_characteristicVector.back();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            // If the request was successful but the 128 bit uuid not found
 | 
				
			||||||
 | 
					            // try again with the 16 bit uuid.
 | 
				
			||||||
 | 
					            NimBLEUUID uuid16(uuid);
 | 
				
			||||||
 | 
					            uuid16.to16();
 | 
				
			||||||
 | 
					            // if the uuid was 128 bit but not of the BLE base type this check will fail
 | 
				
			||||||
 | 
					            if (uuid16.bitSize() == BLE_UUID_TYPE_16) {
 | 
				
			||||||
 | 
					                if(retrieveCharacteristics(&uuid16)) {
 | 
				
			||||||
 | 
					                    if(m_characteristicVector.size() > prev_size) {
 | 
				
			||||||
 | 
					                        return m_characteristicVector.back();
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, "<< getCharacteristic: not found");
 | 
				
			||||||
 | 
					    return nullptr;
 | 
				
			||||||
 | 
					} // getCharacteristic
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get a pointer to the vector of found characteristics.
 | 
				
			||||||
 | 
					 * @param [in] refresh If true the current characteristics vector will cleared and
 | 
				
			||||||
 | 
					 * all characteristics for this service retrieved from the peripheral.
 | 
				
			||||||
 | 
					 * If false the vector will be returned with the currently stored characteristics of this service.
 | 
				
			||||||
 | 
					 * @return A pointer to the vector of descriptors for this characteristic.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					std::vector<NimBLERemoteCharacteristic*>* NimBLERemoteService::getCharacteristics(bool refresh) {
 | 
				
			||||||
 | 
					    if(refresh) {
 | 
				
			||||||
 | 
					        deleteCharacteristics();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!retrieveCharacteristics()) {
 | 
				
			||||||
 | 
					            NIMBLE_LOGE(LOG_TAG, "Error: Failed to get characteristics");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else{
 | 
				
			||||||
 | 
					            NIMBLE_LOGI(LOG_TAG, "Found %d characteristics", m_characteristicVector.size());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return &m_characteristicVector;
 | 
				
			||||||
 | 
					} // getCharacteristics
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Callback for Characterisic discovery.
 | 
				
			||||||
 | 
					 * @return success == 0 or error code.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int NimBLERemoteService::characteristicDiscCB(uint16_t conn_handle,
 | 
				
			||||||
 | 
					                                const struct ble_gatt_error *error,
 | 
				
			||||||
 | 
					                                const struct ble_gatt_chr *chr, void *arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG,"Characteristic Discovered >> status: %d handle: %d",
 | 
				
			||||||
 | 
					                        error->status, (error->status == 0) ? chr->val_handle : -1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ble_task_data_t *pTaskData = (ble_task_data_t*)arg;
 | 
				
			||||||
 | 
					    NimBLERemoteService *service = (NimBLERemoteService*)pTaskData->pATT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Make sure the discovery is for this device
 | 
				
			||||||
 | 
					    if(service->getClient()->getConnId() != conn_handle){
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(error->status == 0) {
 | 
				
			||||||
 | 
					        // Found a service - add it to the vector
 | 
				
			||||||
 | 
					        NimBLERemoteCharacteristic* pRemoteCharacteristic = new NimBLERemoteCharacteristic(service, chr);
 | 
				
			||||||
 | 
					        service->m_characteristicVector.push_back(pRemoteCharacteristic);
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(error->status == BLE_HS_EDONE) {
 | 
				
			||||||
 | 
					        pTaskData->rc = 0;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        NIMBLE_LOGE(LOG_TAG, "characteristicDiscCB() rc=%d %s",
 | 
				
			||||||
 | 
					                             error->status,
 | 
				
			||||||
 | 
					                             NimBLEUtils::returnCodeToString(error->status));
 | 
				
			||||||
 | 
					        pTaskData->rc = error->status;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    xTaskNotifyGive(pTaskData->task);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG,"<< Characteristic Discovered");
 | 
				
			||||||
 | 
					    return error->status;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Retrieve all the characteristics for this service.
 | 
				
			||||||
 | 
					 * This function will not return until we have all the characteristics.
 | 
				
			||||||
 | 
					 * @return True if successful.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool NimBLERemoteService::retrieveCharacteristics(const NimBLEUUID *uuid_filter) {
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, ">> retrieveCharacteristics() for service: %s", getUUID().toString().c_str());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int rc = 0;
 | 
				
			||||||
 | 
					    TaskHandle_t cur_task = xTaskGetCurrentTaskHandle();
 | 
				
			||||||
 | 
					    ble_task_data_t taskData = {this, cur_task, 0, nullptr};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(uuid_filter == nullptr) {
 | 
				
			||||||
 | 
					        rc = ble_gattc_disc_all_chrs(m_pClient->getConnId(),
 | 
				
			||||||
 | 
					                             m_startHandle,
 | 
				
			||||||
 | 
					                             m_endHandle,
 | 
				
			||||||
 | 
					                             NimBLERemoteService::characteristicDiscCB,
 | 
				
			||||||
 | 
					                             &taskData);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        rc = ble_gattc_disc_chrs_by_uuid(m_pClient->getConnId(),
 | 
				
			||||||
 | 
					                             m_startHandle,
 | 
				
			||||||
 | 
					                             m_endHandle,
 | 
				
			||||||
 | 
					                             &uuid_filter->getNative()->u,
 | 
				
			||||||
 | 
					                             NimBLERemoteService::characteristicDiscCB,
 | 
				
			||||||
 | 
					                             &taskData);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (rc != 0) {
 | 
				
			||||||
 | 
					        NIMBLE_LOGE(LOG_TAG, "ble_gattc_disc_all_chrs: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef ulTaskNotifyValueClear
 | 
				
			||||||
 | 
					    // Clear the task notification value to ensure we block
 | 
				
			||||||
 | 
					    ulTaskNotifyValueClear(cur_task, ULONG_MAX);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(taskData.rc == 0){
 | 
				
			||||||
 | 
					        if (uuid_filter == nullptr) {
 | 
				
			||||||
 | 
					            if (m_characteristicVector.size() > 1) {
 | 
				
			||||||
 | 
					                for (auto it = m_characteristicVector.begin(); it != m_characteristicVector.end(); ++it ) {
 | 
				
			||||||
 | 
					                    auto nx = std::next(it, 1);
 | 
				
			||||||
 | 
					                    if (nx == m_characteristicVector.end()) {
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    (*it)->m_endHandle = (*nx)->m_defHandle - 1;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            m_characteristicVector.back()->m_endHandle = getEndHandle();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        NIMBLE_LOGD(LOG_TAG, "<< retrieveCharacteristics()");
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NIMBLE_LOGE(LOG_TAG, "Could not retrieve characteristics");
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // retrieveCharacteristics
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the client associated with this service.
 | 
				
			||||||
 | 
					 * @return A reference to the client associated with this service.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEClient* NimBLERemoteService::getClient() {
 | 
				
			||||||
 | 
					    return m_pClient;
 | 
				
			||||||
 | 
					} // getClient
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the service end handle.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint16_t NimBLERemoteService::getEndHandle() {
 | 
				
			||||||
 | 
					    return m_endHandle;
 | 
				
			||||||
 | 
					} // getEndHandle
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the service start handle.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint16_t NimBLERemoteService::getStartHandle() {
 | 
				
			||||||
 | 
					    return m_startHandle;
 | 
				
			||||||
 | 
					} // getStartHandle
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the service UUID.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEUUID NimBLERemoteService::getUUID() {
 | 
				
			||||||
 | 
					    return m_uuid;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Read the value of a characteristic associated with this service.
 | 
				
			||||||
 | 
					 * @param [in] characteristicUuid The characteristic to read.
 | 
				
			||||||
 | 
					 * @returns a string containing the value or an empty string if not found or error.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					std::string NimBLERemoteService::getValue(const NimBLEUUID &characteristicUuid) {
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, ">> readValue: uuid: %s", characteristicUuid.toString().c_str());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::string ret = "";
 | 
				
			||||||
 | 
					    NimBLERemoteCharacteristic* pChar = getCharacteristic(characteristicUuid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(pChar != nullptr) {
 | 
				
			||||||
 | 
					        ret =  pChar->readValue();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, "<< readValue");
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					} // readValue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set the value of a characteristic.
 | 
				
			||||||
 | 
					 * @param [in] characteristicUuid The characteristic to set.
 | 
				
			||||||
 | 
					 * @param [in] value The value to set.
 | 
				
			||||||
 | 
					 * @returns true on success, false if not found or error
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool NimBLERemoteService::setValue(const NimBLEUUID &characteristicUuid, const std::string &value) {
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, ">> setValue: uuid: %s", characteristicUuid.toString().c_str());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool ret = false;
 | 
				
			||||||
 | 
					    NimBLERemoteCharacteristic* pChar = getCharacteristic(characteristicUuid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(pChar != nullptr) {
 | 
				
			||||||
 | 
					         ret =  pChar->writeValue(value);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, "<< setValue");
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					} // setValue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Delete the characteristics in the characteristics vector.
 | 
				
			||||||
 | 
					 * @details We maintain a vector called m_characteristicsVector that contains pointers to BLERemoteCharacteristic
 | 
				
			||||||
 | 
					 * object references. Since we allocated these in this class, we are also responsible for deleting
 | 
				
			||||||
 | 
					 * them. This method does just that.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLERemoteService::deleteCharacteristics() {
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, ">> deleteCharacteristics");
 | 
				
			||||||
 | 
					    for(auto &it: m_characteristicVector) {
 | 
				
			||||||
 | 
					        delete it;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    m_characteristicVector.clear();
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, "<< deleteCharacteristics");
 | 
				
			||||||
 | 
					} // deleteCharacteristics
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Delete characteristic by UUID
 | 
				
			||||||
 | 
					 * @param [in] uuid The UUID of the characteristic to be removed from the local database.
 | 
				
			||||||
 | 
					 * @return Number of characteristics left.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					size_t NimBLERemoteService::deleteCharacteristic(const NimBLEUUID &uuid) {
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, ">> deleteCharacteristic");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for(auto it = m_characteristicVector.begin(); it != m_characteristicVector.end(); ++it) {
 | 
				
			||||||
 | 
					        if((*it)->getUUID() == uuid) {
 | 
				
			||||||
 | 
					            delete *it;
 | 
				
			||||||
 | 
					            m_characteristicVector.erase(it);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, "<< deleteCharacteristic");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return m_characteristicVector.size();
 | 
				
			||||||
 | 
					} // deleteCharacteristic
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Create a string representation of this remote service.
 | 
				
			||||||
 | 
					 * @return A string representation of this remote service.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					std::string NimBLERemoteService::toString() {
 | 
				
			||||||
 | 
					    std::string res = "Service: uuid: " + m_uuid.toString();
 | 
				
			||||||
 | 
					    char val[6];
 | 
				
			||||||
 | 
					    res += ", start_handle: ";
 | 
				
			||||||
 | 
					    snprintf(val, sizeof(val), "%d", m_startHandle);
 | 
				
			||||||
 | 
					    res += val;
 | 
				
			||||||
 | 
					    snprintf(val, sizeof(val), "%04x", m_startHandle);
 | 
				
			||||||
 | 
					    res += " 0x";
 | 
				
			||||||
 | 
					    res += val;
 | 
				
			||||||
 | 
					    res += ", end_handle: ";
 | 
				
			||||||
 | 
					    snprintf(val, sizeof(val), "%d", m_endHandle);
 | 
				
			||||||
 | 
					    res += val;
 | 
				
			||||||
 | 
					    snprintf(val, sizeof(val), "%04x", m_endHandle);
 | 
				
			||||||
 | 
					    res += " 0x";
 | 
				
			||||||
 | 
					    res += val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (auto &it: m_characteristicVector) {
 | 
				
			||||||
 | 
					        res += "\n" + it->toString();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return res;
 | 
				
			||||||
 | 
					} // toString
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_CENTRAL */
 | 
				
			||||||
@@ -0,0 +1,85 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * NimBLERemoteService.h
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created: on Jan 27 2020
 | 
				
			||||||
 | 
					 *      Author H2zero
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Originally:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * BLERemoteService.h
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created on: Jul 8, 2017
 | 
				
			||||||
 | 
					 *      Author: kolban
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef COMPONENTS_NIMBLEREMOTESERVICE_H_
 | 
				
			||||||
 | 
					#define COMPONENTS_NIMBLEREMOTESERVICE_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "nimconfig.h"
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "NimBLEClient.h"
 | 
				
			||||||
 | 
					#include "NimBLEUUID.h"
 | 
				
			||||||
 | 
					#include "NimBLERemoteCharacteristic.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <vector>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class NimBLEClient;
 | 
				
			||||||
 | 
					class NimBLERemoteCharacteristic;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief A model of a remote %BLE service.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class NimBLERemoteService {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    virtual ~NimBLERemoteService();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Public methods
 | 
				
			||||||
 | 
					    std::vector<NimBLERemoteCharacteristic*>::iterator begin();
 | 
				
			||||||
 | 
					    std::vector<NimBLERemoteCharacteristic*>::iterator end();
 | 
				
			||||||
 | 
					    NimBLERemoteCharacteristic*               getCharacteristic(const char* uuid);
 | 
				
			||||||
 | 
					    NimBLERemoteCharacteristic*               getCharacteristic(const NimBLEUUID &uuid);
 | 
				
			||||||
 | 
					    void                                      deleteCharacteristics();
 | 
				
			||||||
 | 
					    size_t                                    deleteCharacteristic(const NimBLEUUID &uuid);
 | 
				
			||||||
 | 
					    NimBLEClient*                             getClient(void);
 | 
				
			||||||
 | 
					    //uint16_t                                  getHandle();
 | 
				
			||||||
 | 
					    NimBLEUUID                                getUUID(void);
 | 
				
			||||||
 | 
					    std::string                               getValue(const NimBLEUUID &characteristicUuid);
 | 
				
			||||||
 | 
					    bool                                      setValue(const NimBLEUUID &characteristicUuid,
 | 
				
			||||||
 | 
					                                                       const std::string &value);
 | 
				
			||||||
 | 
					    std::string                               toString(void);
 | 
				
			||||||
 | 
					    std::vector<NimBLERemoteCharacteristic*>* getCharacteristics(bool refresh = false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    // Private constructor ... never meant to be created by a user application.
 | 
				
			||||||
 | 
					    NimBLERemoteService(NimBLEClient* pClient, const struct ble_gatt_svc *service);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Friends
 | 
				
			||||||
 | 
					    friend class NimBLEClient;
 | 
				
			||||||
 | 
					    friend class NimBLERemoteCharacteristic;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Private methods
 | 
				
			||||||
 | 
					    bool                retrieveCharacteristics(const NimBLEUUID *uuid_filter = nullptr);
 | 
				
			||||||
 | 
					    static int          characteristicDiscCB(uint16_t conn_handle,
 | 
				
			||||||
 | 
					                                             const struct ble_gatt_error *error,
 | 
				
			||||||
 | 
					                                             const struct ble_gatt_chr *chr,
 | 
				
			||||||
 | 
					                                             void *arg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint16_t            getStartHandle();
 | 
				
			||||||
 | 
					    uint16_t            getEndHandle();
 | 
				
			||||||
 | 
					    void                releaseSemaphores();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Properties
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // We maintain a vector of characteristics owned by this service.
 | 
				
			||||||
 | 
					    std::vector<NimBLERemoteCharacteristic*> m_characteristicVector;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NimBLEClient*       m_pClient;
 | 
				
			||||||
 | 
					    NimBLEUUID          m_uuid;
 | 
				
			||||||
 | 
					    uint16_t            m_startHandle;
 | 
				
			||||||
 | 
					    uint16_t            m_endHandle;
 | 
				
			||||||
 | 
					}; // NimBLERemoteService
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_CENTRAL */
 | 
				
			||||||
 | 
					#endif /* COMPONENTS_NIMBLEREMOTESERVICE_H_ */
 | 
				
			||||||
							
								
								
									
										541
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEScan.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										541
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEScan.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,541 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * NimBLEScan.cpp
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created: on Jan 24 2020
 | 
				
			||||||
 | 
					 *      Author H2zero
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Originally:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * BLEScan.cpp
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created on: Jul 1, 2017
 | 
				
			||||||
 | 
					 *      Author: kolban
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "nimconfig.h"
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "NimBLEScan.h"
 | 
				
			||||||
 | 
					#include "NimBLEDevice.h"
 | 
				
			||||||
 | 
					#include "NimBLELog.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					#include <climits>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char* LOG_TAG = "NimBLEScan";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Scan constuctor.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEScan::NimBLEScan() {
 | 
				
			||||||
 | 
					    m_scan_params.filter_policy      = BLE_HCI_SCAN_FILT_NO_WL;
 | 
				
			||||||
 | 
					    m_scan_params.passive            = 1; // If set, don’t send scan requests to advertisers (i.e., don’t request additional advertising data).
 | 
				
			||||||
 | 
					    m_scan_params.itvl               = 0; // This is defined as the time interval from when the Controller started its last LE scan until it begins the subsequent LE scan. (units=0.625 msec)
 | 
				
			||||||
 | 
					    m_scan_params.window             = 0; // The duration of the LE scan. LE_Scan_Window shall be less than or equal to LE_Scan_Interval (units=0.625 msec)
 | 
				
			||||||
 | 
					    m_scan_params.limited            = 0; // If set, only discover devices in limited discoverable mode.
 | 
				
			||||||
 | 
					    m_scan_params.filter_duplicates  = 0; // If set, the controller ignores all but the first advertisement from each device.
 | 
				
			||||||
 | 
					    m_pAdvertisedDeviceCallbacks     = nullptr;
 | 
				
			||||||
 | 
					    m_ignoreResults                  = false;
 | 
				
			||||||
 | 
					    m_pTaskData                      = nullptr;
 | 
				
			||||||
 | 
					    m_duration                       = BLE_HS_FOREVER; // make sure this is non-zero in the event of a host reset
 | 
				
			||||||
 | 
					    m_maxResults                     = 0xFF;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Scan destructor, release any allocated resources.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEScan::~NimBLEScan() {
 | 
				
			||||||
 | 
					     clearResults();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Handle GAP events related to scans.
 | 
				
			||||||
 | 
					 * @param [in] event The event type for this event.
 | 
				
			||||||
 | 
					 * @param [in] param Parameter data for this event.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					/*STATIC*/int NimBLEScan::handleGapEvent(ble_gap_event* event, void* arg) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NimBLEScan* pScan = (NimBLEScan*)arg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    switch(event->type) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case BLE_GAP_EVENT_DISC: {
 | 
				
			||||||
 | 
					            if(pScan->m_ignoreResults) {
 | 
				
			||||||
 | 
					                NIMBLE_LOGI(LOG_TAG, "Scan op in progress - ignoring results");
 | 
				
			||||||
 | 
					                return 0;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            NimBLEAddress advertisedAddress(event->disc.addr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Examine our list of ignored addresses and stop processing if we don't want to see it or are already connected
 | 
				
			||||||
 | 
					            if(NimBLEDevice::isIgnored(advertisedAddress)) {
 | 
				
			||||||
 | 
					                NIMBLE_LOGI(LOG_TAG, "Ignoring device: address: %s", advertisedAddress.toString().c_str());
 | 
				
			||||||
 | 
					                return 0;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            NimBLEAdvertisedDevice* advertisedDevice = nullptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // If we've seen this device before get a pointer to it from the vector
 | 
				
			||||||
 | 
					            for(auto &it: pScan->m_scanResults.m_advertisedDevicesVector) {
 | 
				
			||||||
 | 
					                if(it->getAddress() == advertisedAddress) {
 | 
				
			||||||
 | 
					                    advertisedDevice = it;
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // If we haven't seen this device before; create a new instance and insert it in the vector.
 | 
				
			||||||
 | 
					            // Otherwise just update the relevant parameters of the already known device.
 | 
				
			||||||
 | 
					            if(advertisedDevice == nullptr && event->disc.event_type != BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP){
 | 
				
			||||||
 | 
					                // Check if we have reach the scan results limit, ignore this one if so.
 | 
				
			||||||
 | 
					                // We still need to store each device when maxResults is 0 to be able to append the scan results
 | 
				
			||||||
 | 
					                if(pScan->m_maxResults > 0 && pScan->m_maxResults < 0xFF &&
 | 
				
			||||||
 | 
					                  (pScan->m_scanResults.m_advertisedDevicesVector.size() >= pScan->m_maxResults))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    return 0;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                advertisedDevice = new NimBLEAdvertisedDevice();
 | 
				
			||||||
 | 
					                advertisedDevice->setAddress(advertisedAddress);
 | 
				
			||||||
 | 
					                advertisedDevice->setAdvType(event->disc.event_type);
 | 
				
			||||||
 | 
					                pScan->m_scanResults.m_advertisedDevicesVector.push_back(advertisedDevice);
 | 
				
			||||||
 | 
					                NIMBLE_LOGI(LOG_TAG, "New advertiser: %s", advertisedAddress.toString().c_str());
 | 
				
			||||||
 | 
					            } else if(advertisedDevice != nullptr) {
 | 
				
			||||||
 | 
					                NIMBLE_LOGI(LOG_TAG, "Updated advertiser: %s", advertisedAddress.toString().c_str());
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                // Scan response from unknown device
 | 
				
			||||||
 | 
					                return 0;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            advertisedDevice->m_timestamp = time(nullptr);
 | 
				
			||||||
 | 
					            advertisedDevice->setRSSI(event->disc.rssi);
 | 
				
			||||||
 | 
					            advertisedDevice->setPayload(event->disc.data, event->disc.length_data,
 | 
				
			||||||
 | 
					            event->disc.event_type == BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (pScan->m_pAdvertisedDeviceCallbacks) {
 | 
				
			||||||
 | 
					                // If not active scanning or scan response is not available
 | 
				
			||||||
 | 
					                // report the result to the callback now.
 | 
				
			||||||
 | 
					                if(pScan->m_scan_params.passive ||
 | 
				
			||||||
 | 
					                  (advertisedDevice->getAdvType() != BLE_HCI_ADV_TYPE_ADV_IND &&
 | 
				
			||||||
 | 
					                   advertisedDevice->getAdvType() != BLE_HCI_ADV_TYPE_ADV_SCAN_IND))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    advertisedDevice->m_callbackSent = true;
 | 
				
			||||||
 | 
					                    pScan->m_pAdvertisedDeviceCallbacks->onResult(advertisedDevice);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // Otherwise, wait for the scan response so we can report the complete data.
 | 
				
			||||||
 | 
					                } else if (event->disc.event_type == BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP) {
 | 
				
			||||||
 | 
					                    advertisedDevice->m_callbackSent = true;
 | 
				
			||||||
 | 
					                    pScan->m_pAdvertisedDeviceCallbacks->onResult(advertisedDevice);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                // If not storing results and we have invoked the callback, delete the device.
 | 
				
			||||||
 | 
					                if(pScan->m_maxResults == 0 && advertisedDevice->m_callbackSent) {
 | 
				
			||||||
 | 
					                    pScan->erase(advertisedAddress);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return 0;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        case BLE_GAP_EVENT_DISC_COMPLETE: {
 | 
				
			||||||
 | 
					            NIMBLE_LOGD(LOG_TAG, "discovery complete; reason=%d",
 | 
				
			||||||
 | 
					                        event->disc_complete.reason);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // If a device advertised with scan reponse available and it was not received
 | 
				
			||||||
 | 
					            // the callback would not have been invoked, so do it here.
 | 
				
			||||||
 | 
					            if(pScan->m_pAdvertisedDeviceCallbacks) {
 | 
				
			||||||
 | 
					                for(auto &it : pScan->m_scanResults.m_advertisedDevicesVector) {
 | 
				
			||||||
 | 
					                    if(!it->m_callbackSent) {
 | 
				
			||||||
 | 
					                        pScan->m_pAdvertisedDeviceCallbacks->onResult(it);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if(pScan->m_maxResults == 0) {
 | 
				
			||||||
 | 
					                pScan->clearResults();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (pScan->m_scanCompleteCB != nullptr) {
 | 
				
			||||||
 | 
					                pScan->m_scanCompleteCB(pScan->m_scanResults);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if(pScan->m_pTaskData != nullptr) {
 | 
				
			||||||
 | 
					                pScan->m_pTaskData->rc = event->disc_complete.reason;
 | 
				
			||||||
 | 
					                xTaskNotifyGive(pScan->m_pTaskData->task);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return 0;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        default:
 | 
				
			||||||
 | 
					            return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}  // gapEventHandler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Should we perform an active or passive scan?
 | 
				
			||||||
 | 
					 * The default is a passive scan. An active scan means that we will request a scan response.
 | 
				
			||||||
 | 
					 * @param [in] active If true, we perform an active scan otherwise a passive scan.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEScan::setActiveScan(bool active) {
 | 
				
			||||||
 | 
					    m_scan_params.passive = !active;
 | 
				
			||||||
 | 
					} // setActiveScan
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set whether or not the BLE controller should only report results
 | 
				
			||||||
 | 
					 * from devices it has not already seen.
 | 
				
			||||||
 | 
					 * @param [in] enabled If true, scanned devices will only be reported once.
 | 
				
			||||||
 | 
					 * @details The controller has a limited buffer and will start reporting
 | 
				
			||||||
 | 
					 * dupicate devices once the limit is reached.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEScan::setDuplicateFilter(bool enabled) {
 | 
				
			||||||
 | 
					    m_scan_params.filter_duplicates = enabled;
 | 
				
			||||||
 | 
					} // setDuplicateFilter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set whether or not the BLE controller only report scan results
 | 
				
			||||||
 | 
					 * from devices advertising in limited discovery mode, i.e. directed advertising.
 | 
				
			||||||
 | 
					 * @param [in] enabled If true, only limited discovery devices will be in scan results.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEScan::setLimitedOnly(bool enabled) {
 | 
				
			||||||
 | 
					    m_scan_params.limited = enabled;
 | 
				
			||||||
 | 
					} // setLimited
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Sets the scan filter policy.
 | 
				
			||||||
 | 
					 * @param [in] filter Can be one of:
 | 
				
			||||||
 | 
					 * * BLE_HCI_SCAN_FILT_NO_WL             (0)
 | 
				
			||||||
 | 
					 *      Scanner processes all advertising packets (white list not used) except\n
 | 
				
			||||||
 | 
					 *      directed, connectable advertising packets not sent to the scanner.
 | 
				
			||||||
 | 
					 * * BLE_HCI_SCAN_FILT_USE_WL            (1)
 | 
				
			||||||
 | 
					 *      Scanner processes advertisements from white list only. A connectable,\n
 | 
				
			||||||
 | 
					 *      directed advertisment is ignored unless it contains scanners address.
 | 
				
			||||||
 | 
					 * * BLE_HCI_SCAN_FILT_NO_WL_INITA       (2)
 | 
				
			||||||
 | 
					 *      Scanner process all advertising packets (white list not used). A\n
 | 
				
			||||||
 | 
					 *      connectable, directed advertisement shall not be ignored if the InitA
 | 
				
			||||||
 | 
					 *      is a resolvable private address.
 | 
				
			||||||
 | 
					 * * BLE_HCI_SCAN_FILT_USE_WL_INITA      (3)
 | 
				
			||||||
 | 
					 *      Scanner process advertisements from white list only. A connectable,\n
 | 
				
			||||||
 | 
					 *      directed advertisement shall not be ignored if the InitA is a
 | 
				
			||||||
 | 
					 *      resolvable private address.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEScan::setFilterPolicy(uint8_t filter) {
 | 
				
			||||||
 | 
					    m_scan_params.filter_policy = filter;
 | 
				
			||||||
 | 
					} // setFilterPolicy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Sets the max number of results to store.
 | 
				
			||||||
 | 
					 * @param [in] maxResults The number of results to limit storage to\n
 | 
				
			||||||
 | 
					 * 0 == none (callbacks only) 0xFF == unlimited, any other value is the limit.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEScan::setMaxResults(uint8_t maxResults) {
 | 
				
			||||||
 | 
					    m_maxResults = maxResults;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set the call backs to be invoked.
 | 
				
			||||||
 | 
					 * @param [in] pAdvertisedDeviceCallbacks Call backs to be invoked.
 | 
				
			||||||
 | 
					 * @param [in] wantDuplicates  True if we wish to be called back with duplicates.  Default is false.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEScan::setAdvertisedDeviceCallbacks(NimBLEAdvertisedDeviceCallbacks* pAdvertisedDeviceCallbacks,
 | 
				
			||||||
 | 
					                                              bool wantDuplicates) {
 | 
				
			||||||
 | 
					    setDuplicateFilter(!wantDuplicates);
 | 
				
			||||||
 | 
					    m_pAdvertisedDeviceCallbacks = pAdvertisedDeviceCallbacks;
 | 
				
			||||||
 | 
					} // setAdvertisedDeviceCallbacks
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set the interval to scan.
 | 
				
			||||||
 | 
					 * @param [in] intervalMSecs The scan interval (how often) in milliseconds.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEScan::setInterval(uint16_t intervalMSecs) {
 | 
				
			||||||
 | 
					    m_scan_params.itvl = intervalMSecs / 0.625;
 | 
				
			||||||
 | 
					} // setInterval
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set the window to actively scan.
 | 
				
			||||||
 | 
					 * @param [in] windowMSecs How long to actively scan.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEScan::setWindow(uint16_t windowMSecs) {
 | 
				
			||||||
 | 
					    m_scan_params.window = windowMSecs / 0.625;
 | 
				
			||||||
 | 
					} // setWindow
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the status of the scanner.
 | 
				
			||||||
 | 
					 * @return true if scanning or scan starting.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool NimBLEScan::isScanning() {
 | 
				
			||||||
 | 
					    return ble_gap_disc_active();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Start scanning.
 | 
				
			||||||
 | 
					 * @param [in] duration The duration in seconds for which to scan.
 | 
				
			||||||
 | 
					 * @param [in] scanCompleteCB A function to be called when scanning has completed.
 | 
				
			||||||
 | 
					 * @param [in] is_continue Set to true to save previous scan results, false to clear them.
 | 
				
			||||||
 | 
					 * @return True if scan started or false if there was an error.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool NimBLEScan::start(uint32_t duration, void (*scanCompleteCB)(NimBLEScanResults), bool is_continue) {
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, ">> start: duration=%" PRIu32, duration);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Save the callback to be invoked when the scan completes.
 | 
				
			||||||
 | 
					    m_scanCompleteCB = scanCompleteCB;
 | 
				
			||||||
 | 
					    // Save the duration in the case that the host is reset so we can reuse it.
 | 
				
			||||||
 | 
					    m_duration = duration;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // If 0 duration specified then we assume a continuous scan is desired.
 | 
				
			||||||
 | 
					    if(duration == 0){
 | 
				
			||||||
 | 
					        duration = BLE_HS_FOREVER;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else{
 | 
				
			||||||
 | 
					        // convert duration to milliseconds
 | 
				
			||||||
 | 
					        duration = duration * 1000;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Set the flag to ignore the results while we are deleting the vector
 | 
				
			||||||
 | 
					    if(!is_continue) {
 | 
				
			||||||
 | 
					        m_ignoreResults = true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int rc = ble_gap_disc(NimBLEDevice::m_own_addr_type, duration, &m_scan_params,
 | 
				
			||||||
 | 
					                          NimBLEScan::handleGapEvent, this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    switch(rc) {
 | 
				
			||||||
 | 
					        case 0:
 | 
				
			||||||
 | 
					            if(!is_continue) {
 | 
				
			||||||
 | 
					                clearResults();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case BLE_HS_EALREADY:
 | 
				
			||||||
 | 
					            // Clear the cache if already scanning in case an advertiser was missed.
 | 
				
			||||||
 | 
					            clearDuplicateCache();
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case BLE_HS_EBUSY:
 | 
				
			||||||
 | 
					            NIMBLE_LOGE(LOG_TAG, "Unable to scan - connection in progress.");
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case BLE_HS_ETIMEOUT_HCI:
 | 
				
			||||||
 | 
					        case BLE_HS_EOS:
 | 
				
			||||||
 | 
					        case BLE_HS_ECONTROLLER:
 | 
				
			||||||
 | 
					        case BLE_HS_ENOTSYNCED:
 | 
				
			||||||
 | 
					            NIMBLE_LOGC(LOG_TAG, "Unable to scan - Host Reset");
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        default:
 | 
				
			||||||
 | 
					            NIMBLE_LOGE(LOG_TAG, "Error initiating GAP discovery procedure; rc=%d, %s",
 | 
				
			||||||
 | 
					                        rc, NimBLEUtils::returnCodeToString(rc));
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    m_ignoreResults = false;
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, "<< start()");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(rc != 0 && rc != BLE_HS_EALREADY) {
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					} // start
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Start scanning and block until scanning has been completed.
 | 
				
			||||||
 | 
					 * @param [in] duration The duration in seconds for which to scan.
 | 
				
			||||||
 | 
					 * @param [in] is_continue Set to true to save previous scan results, false to clear them.
 | 
				
			||||||
 | 
					 * @return The NimBLEScanResults.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEScanResults NimBLEScan::start(uint32_t duration, bool is_continue) {
 | 
				
			||||||
 | 
					    if(duration == 0) {
 | 
				
			||||||
 | 
					        NIMBLE_LOGW(LOG_TAG, "Blocking scan called with duration = forever");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    TaskHandle_t cur_task = xTaskGetCurrentTaskHandle();
 | 
				
			||||||
 | 
					    ble_task_data_t taskData = {nullptr, cur_task, 0, nullptr};
 | 
				
			||||||
 | 
					    m_pTaskData = &taskData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(start(duration, nullptr, is_continue)) {
 | 
				
			||||||
 | 
					#ifdef ulTaskNotifyValueClear
 | 
				
			||||||
 | 
					        // Clear the task notification value to ensure we block
 | 
				
			||||||
 | 
					        ulTaskNotifyValueClear(cur_task, ULONG_MAX);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    m_pTaskData = nullptr;
 | 
				
			||||||
 | 
					    return m_scanResults;
 | 
				
			||||||
 | 
					} // start
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Stop an in progress scan.
 | 
				
			||||||
 | 
					 * @return True if successful.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool NimBLEScan::stop() {
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, ">> stop()");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int rc = ble_gap_disc_cancel();
 | 
				
			||||||
 | 
					    if (rc != 0 && rc != BLE_HS_EALREADY) {
 | 
				
			||||||
 | 
					        NIMBLE_LOGE(LOG_TAG, "Failed to cancel scan; rc=%d", rc);
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(m_maxResults == 0) {
 | 
				
			||||||
 | 
					        clearResults();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (rc != BLE_HS_EALREADY && m_scanCompleteCB != nullptr) {
 | 
				
			||||||
 | 
					        m_scanCompleteCB(m_scanResults);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(m_pTaskData != nullptr) {
 | 
				
			||||||
 | 
					        xTaskNotifyGive(m_pTaskData->task);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, "<< stop()");
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					} // stop
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Clears the duplicate scan filter cache.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEScan::clearDuplicateCache() {
 | 
				
			||||||
 | 
					#ifdef CONFIG_IDF_TARGET_ESP32 // Not available for ESP32C3
 | 
				
			||||||
 | 
					    esp_ble_scan_dupilcate_list_flush();
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Delete peer device from the scan results vector.
 | 
				
			||||||
 | 
					 * @param [in] address The address of the device to delete from the results.
 | 
				
			||||||
 | 
					 * @details After disconnecting, it may be required in the case we were connected to a device without a public address.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEScan::erase(const NimBLEAddress &address) {
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, "erase device: %s", address.toString().c_str());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for(auto it = m_scanResults.m_advertisedDevicesVector.begin(); it != m_scanResults.m_advertisedDevicesVector.end(); ++it) {
 | 
				
			||||||
 | 
					        if((*it)->getAddress() == address) {
 | 
				
			||||||
 | 
					            delete *it;
 | 
				
			||||||
 | 
					            m_scanResults.m_advertisedDevicesVector.erase(it);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Called when host reset, we set a flag to stop scanning until synced.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEScan::onHostReset() {
 | 
				
			||||||
 | 
					    m_ignoreResults = true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief If the host reset and re-synced this is called.
 | 
				
			||||||
 | 
					 * If the application was scanning indefinitely with a callback, restart it.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEScan::onHostSync() {
 | 
				
			||||||
 | 
					    m_ignoreResults = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(m_duration == 0 && m_pAdvertisedDeviceCallbacks != nullptr) {
 | 
				
			||||||
 | 
					        start(m_duration, m_scanCompleteCB);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the results of the scan.
 | 
				
			||||||
 | 
					 * @return NimBLEScanResults object.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEScanResults NimBLEScan::getResults() {
 | 
				
			||||||
 | 
					    return m_scanResults;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Clear the results of the scan.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEScan::clearResults() {
 | 
				
			||||||
 | 
					    for(auto &it: m_scanResults.m_advertisedDevicesVector) {
 | 
				
			||||||
 | 
					        delete it;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    m_scanResults.m_advertisedDevicesVector.clear();
 | 
				
			||||||
 | 
					    clearDuplicateCache();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Dump the scan results to the log.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLEScanResults::dump() {
 | 
				
			||||||
 | 
					    NIMBLE_LOGD(LOG_TAG, ">> Dump scan results:");
 | 
				
			||||||
 | 
					    for (int i=0; i<getCount(); i++) {
 | 
				
			||||||
 | 
					        NIMBLE_LOGI(LOG_TAG, "- %s", getDevice(i).toString().c_str());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					} // dump
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get the count of devices found in the last scan.
 | 
				
			||||||
 | 
					 * @return The number of devices found in the last scan.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int NimBLEScanResults::getCount() {
 | 
				
			||||||
 | 
					    return m_advertisedDevicesVector.size();
 | 
				
			||||||
 | 
					} // getCount
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Return the specified device at the given index.
 | 
				
			||||||
 | 
					 * The index should be between 0 and getCount()-1.
 | 
				
			||||||
 | 
					 * @param [in] i The index of the device.
 | 
				
			||||||
 | 
					 * @return The device at the specified index.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEAdvertisedDevice NimBLEScanResults::getDevice(uint32_t i) {
 | 
				
			||||||
 | 
					    return *m_advertisedDevicesVector[i];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get iterator to the beginning of the vector of advertised device pointers.
 | 
				
			||||||
 | 
					 * @return An iterator to the beginning of the vector of advertised device pointers.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					std::vector<NimBLEAdvertisedDevice*>::iterator NimBLEScanResults::begin() {
 | 
				
			||||||
 | 
					    return m_advertisedDevicesVector.begin();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get iterator to the end of the vector of advertised device pointers.
 | 
				
			||||||
 | 
					 * @return An iterator to the end of the vector of advertised device pointers.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					std::vector<NimBLEAdvertisedDevice*>::iterator NimBLEScanResults::end() {
 | 
				
			||||||
 | 
					    return m_advertisedDevicesVector.end();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Get a pointer to the specified device at the given address.
 | 
				
			||||||
 | 
					 * If the address is not found a nullptr is returned.
 | 
				
			||||||
 | 
					 * @param [in] address The address of the device.
 | 
				
			||||||
 | 
					 * @return A pointer to the device at the specified address.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					NimBLEAdvertisedDevice *NimBLEScanResults::getDevice(const NimBLEAddress &address) {
 | 
				
			||||||
 | 
					    for(size_t index = 0; index < m_advertisedDevicesVector.size(); index++) {
 | 
				
			||||||
 | 
					        if(m_advertisedDevicesVector[index]->getAddress() == address) {
 | 
				
			||||||
 | 
					            return m_advertisedDevicesVector[index];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return nullptr;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_OBSERVER */
 | 
				
			||||||
							
								
								
									
										103
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEScan.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLEScan.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,103 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * NimBLEScan.h
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created: on Jan 24 2020
 | 
				
			||||||
 | 
					 *      Author H2zero
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Originally:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * BLEScan.h
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created on: Jul 1, 2017
 | 
				
			||||||
 | 
					 *      Author: kolban
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#ifndef COMPONENTS_NIMBLE_SCAN_H_
 | 
				
			||||||
 | 
					#define COMPONENTS_NIMBLE_SCAN_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "nimconfig.h"
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "NimBLEAdvertisedDevice.h"
 | 
				
			||||||
 | 
					#include "NimBLEUtils.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(CONFIG_NIMBLE_CPP_IDF)
 | 
				
			||||||
 | 
					#include "host/ble_gap.h"
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#include "nimble/nimble/host/include/host/ble_gap.h"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <vector>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class NimBLEDevice;
 | 
				
			||||||
 | 
					class NimBLEScan;
 | 
				
			||||||
 | 
					class NimBLEAdvertisedDevice;
 | 
				
			||||||
 | 
					class NimBLEAdvertisedDeviceCallbacks;
 | 
				
			||||||
 | 
					class NimBLEAddress;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief A class that contains and operates on the results of a BLE scan.
 | 
				
			||||||
 | 
					 * @details When a scan completes, we have a set of found devices.  Each device is described
 | 
				
			||||||
 | 
					 * by a NimBLEAdvertisedDevice object.  The number of items in the set is given by
 | 
				
			||||||
 | 
					 * getCount().  We can retrieve a device by calling getDevice() passing in the
 | 
				
			||||||
 | 
					 * index (starting at 0) of the desired device.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class NimBLEScanResults {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    void                                           dump();
 | 
				
			||||||
 | 
					    int                                            getCount();
 | 
				
			||||||
 | 
					    NimBLEAdvertisedDevice                         getDevice(uint32_t i);
 | 
				
			||||||
 | 
					    std::vector<NimBLEAdvertisedDevice*>::iterator begin();
 | 
				
			||||||
 | 
					    std::vector<NimBLEAdvertisedDevice*>::iterator end();
 | 
				
			||||||
 | 
					    NimBLEAdvertisedDevice                         *getDevice(const NimBLEAddress &address);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    friend NimBLEScan;
 | 
				
			||||||
 | 
					    std::vector<NimBLEAdvertisedDevice*> m_advertisedDevicesVector;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Perform and manage %BLE scans.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Scanning is associated with a %BLE client that is attempting to locate BLE servers.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class NimBLEScan {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    bool                start(uint32_t duration, void (*scanCompleteCB)(NimBLEScanResults), bool is_continue = false);
 | 
				
			||||||
 | 
					    NimBLEScanResults   start(uint32_t duration, bool is_continue = false);
 | 
				
			||||||
 | 
					    bool                isScanning();
 | 
				
			||||||
 | 
					    void                setAdvertisedDeviceCallbacks(NimBLEAdvertisedDeviceCallbacks* pAdvertisedDeviceCallbacks, bool wantDuplicates = false);
 | 
				
			||||||
 | 
					    void                setActiveScan(bool active);
 | 
				
			||||||
 | 
					    void                setInterval(uint16_t intervalMSecs);
 | 
				
			||||||
 | 
					    void                setWindow(uint16_t windowMSecs);
 | 
				
			||||||
 | 
					    void                setDuplicateFilter(bool enabled);
 | 
				
			||||||
 | 
					    void                setLimitedOnly(bool enabled);
 | 
				
			||||||
 | 
					    void                setFilterPolicy(uint8_t filter);
 | 
				
			||||||
 | 
					    void                clearDuplicateCache();
 | 
				
			||||||
 | 
					    bool                stop();
 | 
				
			||||||
 | 
					    void                clearResults();
 | 
				
			||||||
 | 
					    NimBLEScanResults   getResults();
 | 
				
			||||||
 | 
					    void                setMaxResults(uint8_t maxResults);
 | 
				
			||||||
 | 
					    void                erase(const NimBLEAddress &address);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    friend class NimBLEDevice;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NimBLEScan();
 | 
				
			||||||
 | 
					    ~NimBLEScan();
 | 
				
			||||||
 | 
					    static int          handleGapEvent(ble_gap_event*  event, void* arg);
 | 
				
			||||||
 | 
					    void                onHostReset();
 | 
				
			||||||
 | 
					    void                onHostSync();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NimBLEAdvertisedDeviceCallbacks*    m_pAdvertisedDeviceCallbacks = nullptr;
 | 
				
			||||||
 | 
					    void                                (*m_scanCompleteCB)(NimBLEScanResults scanResults);
 | 
				
			||||||
 | 
					    ble_gap_disc_params                 m_scan_params;
 | 
				
			||||||
 | 
					    bool                                m_ignoreResults;
 | 
				
			||||||
 | 
					    NimBLEScanResults                   m_scanResults;
 | 
				
			||||||
 | 
					    uint32_t                            m_duration;
 | 
				
			||||||
 | 
					    ble_task_data_t                     *m_pTaskData;
 | 
				
			||||||
 | 
					    uint8_t                             m_maxResults;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* CONFIG_BT_ENABLED CONFIG_BT_NIMBLE_ROLE_OBSERVER */
 | 
				
			||||||
 | 
					#endif /* COMPONENTS_NIMBLE_SCAN_H_ */
 | 
				
			||||||
							
								
								
									
										158
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLESecurity.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLESecurity.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,158 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * NimBLESecurity.cpp
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created: on Feb 22 2020
 | 
				
			||||||
 | 
					 *      Author H2zero
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Originally:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * BLESecurity.cpp
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created on: Dec 17, 2017
 | 
				
			||||||
 | 
					 *      Author: chegewara
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "nimconfig.h"
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_ENABLED)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "NimBLESecurity.h"
 | 
				
			||||||
 | 
					#include "NimBLEDevice.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NimBLESecurity::NimBLESecurity() {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NimBLESecurity::~NimBLESecurity() {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set requested authentication mode
 | 
				
			||||||
 | 
					 * @param [in] auth_req A bitmask containing one or more of:
 | 
				
			||||||
 | 
					 * * ESP_LE_AUTH_NO_BOND              0x00
 | 
				
			||||||
 | 
					 * * ESP_LE_AUTH_BOND                 0x01
 | 
				
			||||||
 | 
					 * * ESP_LE_AUTH_REQ_MITM             (1 << 2)
 | 
				
			||||||
 | 
					 * * ESP_LE_AUTH_REQ_BOND_MITM        (ESP_LE_AUTH_BOND | ESP_LE_AUTH_REQ_MITM)
 | 
				
			||||||
 | 
					 * * ESP_LE_AUTH_REQ_SC_ONLY          (1 << 3)
 | 
				
			||||||
 | 
					 * * ESP_LE_AUTH_REQ_SC_BOND          (ESP_LE_AUTH_BOND | ESP_LE_AUTH_REQ_SC_ONLY)
 | 
				
			||||||
 | 
					 * * ESP_LE_AUTH_REQ_SC_MITM          (ESP_LE_AUTH_REQ_MITM | ESP_LE_AUTH_REQ_SC_ONLY)
 | 
				
			||||||
 | 
					 * * ESP_LE_AUTH_REQ_SC_MITM_BOND     (ESP_LE_AUTH_REQ_MITM | ESP_LE_AUTH_REQ_SC_ONLY | ESP_LE_AUTH_BOND)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLESecurity::setAuthenticationMode(esp_ble_auth_req_t auth_req) {
 | 
				
			||||||
 | 
					    NimBLEDevice::setSecurityAuth((auth_req & BLE_SM_PAIR_AUTHREQ_BOND)>0,
 | 
				
			||||||
 | 
					                                (auth_req & BLE_SM_PAIR_AUTHREQ_MITM)>0,
 | 
				
			||||||
 | 
					                                (auth_req & BLE_SM_PAIR_AUTHREQ_SC)>0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Set our device IO capability to let end user perform authorization
 | 
				
			||||||
 | 
					 * either by displaying or entering generated 6-digit pin code or use \"just works\".
 | 
				
			||||||
 | 
					 * @param [in] iocap  The IO capabilites our device has.\n
 | 
				
			||||||
 | 
					 * Can be set to one of:
 | 
				
			||||||
 | 
					 * * ESP_IO_CAP_OUT                      0
 | 
				
			||||||
 | 
					 * * ESP_IO_CAP_IO                       1
 | 
				
			||||||
 | 
					 * * ESP_IO_CAP_IN                       2
 | 
				
			||||||
 | 
					 * * ESP_IO_CAP_NONE                     3
 | 
				
			||||||
 | 
					 * * ESP_IO_CAP_KBDISP                   4
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLESecurity::setCapability(esp_ble_io_cap_t iocap) {
 | 
				
			||||||
 | 
					    NimBLEDevice::setSecurityIOCap(iocap);
 | 
				
			||||||
 | 
					} // setCapability
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Sets the keys we will distibute during encryption.
 | 
				
			||||||
 | 
					 * @param [in] init_key A bitmask of the keys we will distibute.\n
 | 
				
			||||||
 | 
					 * Can be one or more of:
 | 
				
			||||||
 | 
					 * * ESP_BLE_ENC_KEY_MASK    (1 << 0)
 | 
				
			||||||
 | 
					 * * ESP_BLE_ID_KEY_MASK     (1 << 1)
 | 
				
			||||||
 | 
					 * * ESP_BLE_CSR_KEY_MASK    (1 << 2)
 | 
				
			||||||
 | 
					 * * ESP_BLE_LINK_KEY_MASK   (1 << 3)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLESecurity::setInitEncryptionKey(uint8_t init_key) {
 | 
				
			||||||
 | 
					    NimBLEDevice::setSecurityInitKey(init_key);
 | 
				
			||||||
 | 
					} // setInitEncryptionKey
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Sets the keys we will accept during encryption.
 | 
				
			||||||
 | 
					 * @param [in] resp_key A bitmask of the keys we will accept.\n
 | 
				
			||||||
 | 
					 * Can be one or more of:
 | 
				
			||||||
 | 
					 * * ESP_BLE_ENC_KEY_MASK    (1 << 0)
 | 
				
			||||||
 | 
					 * * ESP_BLE_ID_KEY_MASK     (1 << 1)
 | 
				
			||||||
 | 
					 * * ESP_BLE_CSR_KEY_MASK    (1 << 2)
 | 
				
			||||||
 | 
					 * * ESP_BLE_LINK_KEY_MASK   (1 << 3)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLESecurity::setRespEncryptionKey(uint8_t resp_key) {
 | 
				
			||||||
 | 
					    NimBLEDevice::setSecurityRespKey(resp_key);
 | 
				
			||||||
 | 
					} // setRespEncryptionKey
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 *@todo  Requires implementation
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLESecurity::setKeySize(uint8_t key_size) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //m_keySize = key_size;
 | 
				
			||||||
 | 
					    //esp_ble_gap_set_security_param(ESP_BLE_SM_MAX_KEY_SIZE, &m_keySize, sizeof(uint8_t));
 | 
				
			||||||
 | 
					} //setKeySize
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Sets a static PIN used to authenticate/encrypt the connection.
 | 
				
			||||||
 | 
					 * @param [in] pin The 6 digit pin code to accept.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void NimBLESecurity::setStaticPIN(uint32_t pin){
 | 
				
			||||||
 | 
					    //uint32_t passkey = pin;
 | 
				
			||||||
 | 
					    //esp_ble_gap_set_security_param(ESP_BLE_SM_SET_STATIC_PASSKEY, &passkey, sizeof(uint32_t));
 | 
				
			||||||
 | 
					    NimBLEDevice::setSecurityPasskey(pin);
 | 
				
			||||||
 | 
					    setCapability(ESP_IO_CAP_OUT);
 | 
				
			||||||
 | 
					    setKeySize();
 | 
				
			||||||
 | 
					    setAuthenticationMode(ESP_LE_AUTH_REQ_SC_ONLY);
 | 
				
			||||||
 | 
					    setInitEncryptionKey(ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Debug function to display what keys are exchanged by peers
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					 /*
 | 
				
			||||||
 | 
					char* BLESecurity::esp_key_type_to_str(esp_ble_key_type_t key_type) {
 | 
				
			||||||
 | 
					    char* key_str = nullptr;
 | 
				
			||||||
 | 
					    switch (key_type) {
 | 
				
			||||||
 | 
					        case ESP_LE_KEY_NONE:
 | 
				
			||||||
 | 
					            key_str = (char*) "ESP_LE_KEY_NONE";
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case ESP_LE_KEY_PENC:
 | 
				
			||||||
 | 
					            key_str = (char*) "ESP_LE_KEY_PENC";
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case ESP_LE_KEY_PID:
 | 
				
			||||||
 | 
					            key_str = (char*) "ESP_LE_KEY_PID";
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case ESP_LE_KEY_PCSRK:
 | 
				
			||||||
 | 
					            key_str = (char*) "ESP_LE_KEY_PCSRK";
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case ESP_LE_KEY_PLK:
 | 
				
			||||||
 | 
					            key_str = (char*) "ESP_LE_KEY_PLK";
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case ESP_LE_KEY_LLK:
 | 
				
			||||||
 | 
					            key_str = (char*) "ESP_LE_KEY_LLK";
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case ESP_LE_KEY_LENC:
 | 
				
			||||||
 | 
					            key_str = (char*) "ESP_LE_KEY_LENC";
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case ESP_LE_KEY_LID:
 | 
				
			||||||
 | 
					            key_str = (char*) "ESP_LE_KEY_LID";
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case ESP_LE_KEY_LCSRK:
 | 
				
			||||||
 | 
					            key_str = (char*) "ESP_LE_KEY_LCSRK";
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        default:
 | 
				
			||||||
 | 
					            key_str = (char*) "INVALID BLE KEY TYPE";
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return key_str;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // esp_key_type_to_str
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					#endif // CONFIG_BT_ENABLED
 | 
				
			||||||
							
								
								
									
										131
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLESecurity.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								src/components/esp-nimble-cpp-1.3.3/src/NimBLESecurity.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,131 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * NimBLESecurity.h
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created: on Feb 22 2020
 | 
				
			||||||
 | 
					 *      Author H2zero
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Originally:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * BLESecurity.h
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Created on: Dec 17, 2017
 | 
				
			||||||
 | 
					 *      Author: chegewara
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef COMPONENTS_NIMBLESECURITY_H_
 | 
				
			||||||
 | 
					#define COMPONENTS_NIMBLESECURITY_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "nimconfig.h"
 | 
				
			||||||
 | 
					#if defined(CONFIG_BT_ENABLED)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(CONFIG_NIMBLE_CPP_IDF)
 | 
				
			||||||
 | 
					#include "host/ble_gap.h"
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#include "nimble/nimble/host/include/host/ble_gap.h"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/****  FIX COMPILATION ****/
 | 
				
			||||||
 | 
					#undef min
 | 
				
			||||||
 | 
					#undef max
 | 
				
			||||||
 | 
					/**************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ESP_LE_AUTH_NO_BOND                 0x00                                     /*!< 0*/                     /* relate to BTM_LE_AUTH_NO_BOND in stack/btm_api.h */
 | 
				
			||||||
 | 
					#define ESP_LE_AUTH_BOND                    0x01                                     /*!< 1 << 0 */               /* relate to BTM_LE_AUTH_BOND in stack/btm_api.h */
 | 
				
			||||||
 | 
					#define ESP_LE_AUTH_REQ_MITM                (1 << 2)                                 /*!< 1 << 2 */               /* relate to BTM_LE_AUTH_REQ_MITM in stack/btm_api.h */
 | 
				
			||||||
 | 
					#define ESP_LE_AUTH_REQ_BOND_MITM           (ESP_LE_AUTH_BOND | ESP_LE_AUTH_REQ_MITM)/*!< 0101*/
 | 
				
			||||||
 | 
					#define ESP_LE_AUTH_REQ_SC_ONLY             (1 << 3)                                 /*!< 1 << 3 */               /* relate to BTM_LE_AUTH_REQ_SC_ONLY in stack/btm_api.h */
 | 
				
			||||||
 | 
					#define ESP_LE_AUTH_REQ_SC_BOND             (ESP_LE_AUTH_BOND | ESP_LE_AUTH_REQ_SC_ONLY)            /*!< 1001 */  /* relate to BTM_LE_AUTH_REQ_SC_BOND in stack/btm_api.h */
 | 
				
			||||||
 | 
					#define ESP_LE_AUTH_REQ_SC_MITM             (ESP_LE_AUTH_REQ_MITM | ESP_LE_AUTH_REQ_SC_ONLY)        /*!< 1100 */  /* relate to BTM_LE_AUTH_REQ_SC_MITM in stack/btm_api.h */
 | 
				
			||||||
 | 
					#define ESP_LE_AUTH_REQ_SC_MITM_BOND        (ESP_LE_AUTH_REQ_MITM | ESP_LE_AUTH_REQ_SC_ONLY | ESP_LE_AUTH_BOND)   /*!< 1101 */  /* relate to BTM_LE_AUTH_REQ_SC_MITM_BOND in stack/btm_api.h */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ESP_IO_CAP_OUT                      0   /*!< DisplayOnly */         /* relate to BTM_IO_CAP_OUT in stack/btm_api.h */
 | 
				
			||||||
 | 
					#define ESP_IO_CAP_IO                       1   /*!< DisplayYesNo */        /* relate to BTM_IO_CAP_IO in stack/btm_api.h */
 | 
				
			||||||
 | 
					#define ESP_IO_CAP_IN                       2   /*!< KeyboardOnly */        /* relate to BTM_IO_CAP_IN in stack/btm_api.h */
 | 
				
			||||||
 | 
					#define ESP_IO_CAP_NONE                     3   /*!< NoInputNoOutput */     /* relate to BTM_IO_CAP_NONE in stack/btm_api.h */
 | 
				
			||||||
 | 
					#define ESP_IO_CAP_KBDISP                   4   /*!< Keyboard display */    /* relate to BTM_IO_CAP_KBDISP in stack/btm_api.h */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Used to exchange the encryption key in the init key & response key
 | 
				
			||||||
 | 
					#define ESP_BLE_ENC_KEY_MASK    (1 << 0)            /* relate to BTM_BLE_ENC_KEY_MASK in stack/btm_api.h */
 | 
				
			||||||
 | 
					/// Used to exchange the IRK key in the init key & response key
 | 
				
			||||||
 | 
					#define ESP_BLE_ID_KEY_MASK     (1 << 1)            /* relate to BTM_BLE_ID_KEY_MASK in stack/btm_api.h */
 | 
				
			||||||
 | 
					/// Used to exchange the CSRK key in the init key & response key
 | 
				
			||||||
 | 
					#define ESP_BLE_CSR_KEY_MASK    (1 << 2)            /* relate to BTM_BLE_CSR_KEY_MASK in stack/btm_api.h */
 | 
				
			||||||
 | 
					/// Used to exchange the link key(this key just used in the BLE & BR/EDR coexist mode) in the init key & response key
 | 
				
			||||||
 | 
					#define ESP_BLE_LINK_KEY_MASK   (1 << 3)            /* relate to BTM_BLE_LINK_KEY_MASK in stack/btm_api.h */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef uint8_t   esp_ble_auth_req_t;         /*!< combination of the above bit pattern */
 | 
				
			||||||
 | 
					typedef uint8_t   esp_ble_io_cap_t;               /*!< combination of the io capability */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief A class to handle BLE security operations.
 | 
				
			||||||
 | 
					 * <b>Deprecated - provided for backward compatibility only.</b>
 | 
				
			||||||
 | 
					 * @deprecated Use the security methods provided in NimBLEDevice instead.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class NimBLESecurity {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    NimBLESecurity();
 | 
				
			||||||
 | 
					    virtual ~NimBLESecurity();
 | 
				
			||||||
 | 
					    void setAuthenticationMode(esp_ble_auth_req_t auth_req);
 | 
				
			||||||
 | 
					    void setCapability(esp_ble_io_cap_t iocap);
 | 
				
			||||||
 | 
					    void setInitEncryptionKey(uint8_t init_key);
 | 
				
			||||||
 | 
					    void setRespEncryptionKey(uint8_t resp_key);
 | 
				
			||||||
 | 
					    void setKeySize(uint8_t key_size = 16);
 | 
				
			||||||
 | 
					    void setStaticPIN(uint32_t pin);
 | 
				
			||||||
 | 
					    //static char* esp_key_type_to_str(esp_ble_key_type_t key_type);
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    esp_ble_auth_req_t m_authReq;
 | 
				
			||||||
 | 
					    esp_ble_io_cap_t m_iocap;
 | 
				
			||||||
 | 
					    uint8_t m_initKey;
 | 
				
			||||||
 | 
					    uint8_t m_respKey;
 | 
				
			||||||
 | 
					    uint8_t m_keySize;
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					}; // BLESecurity
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Callbacks to handle GAP events related to authorization.
 | 
				
			||||||
 | 
					 * <b>Deprecated - provided for backward compatibility only.</b>
 | 
				
			||||||
 | 
					 * @deprecated Use the callbacks provided in NimBLEClientCallbacks and NimBLEServerCallbacks instead.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class NimBLESecurityCallbacks {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    virtual ~NimBLESecurityCallbacks() {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Its request from peer device to input authentication pin code displayed on peer device.
 | 
				
			||||||
 | 
					     * It requires that our device is capable to input 6-digits code by end user
 | 
				
			||||||
 | 
					     * @return Return 6-digits integer value from input device
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual uint32_t onPassKeyRequest() = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Provide us 6-digits code to perform authentication.
 | 
				
			||||||
 | 
					     * It requires that our device is capable to display this code to end user
 | 
				
			||||||
 | 
					     * @param [in] pass_key The PIN provided by the peer.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual void onPassKeyNotify(uint32_t pass_key) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Here we can make decision if we want to let negotiate authorization with peer device or not
 | 
				
			||||||
 | 
					     * @return Return true if we accept this peer device request
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual bool onSecurityRequest() = 0 ;
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Provides us information when authentication process is completed
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual void onAuthenticationComplete(ble_gap_conn_desc*) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Called when using numeric comparison for authentication.
 | 
				
			||||||
 | 
					     * @param [in] pin The PIN to compare.
 | 
				
			||||||
 | 
					     * @return True to accept and pair.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual bool onConfirmPIN(uint32_t pin) = 0;
 | 
				
			||||||
 | 
					}; // BLESecurityCallbacks
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // CONFIG_BT_ENABLED
 | 
				
			||||||
 | 
					#endif // COMPONENTS_NIMBLESECURITY_H_
 | 
				
			||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user