component/bt : add bluf that use bluetooth config wifi connection demos

1. add libphy.a librtc.a, but store in bt submodule, if someone use them, please copy to esp32/lib/ instead the origin one
2. add 07_blufi demo
3. change esp32/Kconfig to allow bt/wifi coexist
pull/111/merge
Tian Hao 2016-10-07 11:16:13 +08:00
rodzic 1c877be609
commit eb8cb8d22e
19 zmienionych plików z 2055 dodań i 13 usunięć

Wyświetl plik

@ -54,7 +54,10 @@ static void button_profile_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
{
tBTA_GATTS_RSP rsp;
tBT_UUID uuid = {LEN_UUID_16, {ATT_SVC_BUTTON}};
tBUT_INST *p_inst = &button_cb_env.button_inst;
UINT8 net_event = 0xff;
UINT8 len = 0;
UINT8 *p_rec_data = NULL;
//LOG_ERROR("p_data->status = %x\n",p_data->status);
//if(p_data->status != BTA_GATT_OK){
// LOG_ERROR("button profile register failed\n");
@ -91,6 +94,17 @@ static void button_profile_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
case BTA_GATTS_WRITE_EVT:
BTA_GATTS_SendRsp(p_data->req_data.conn_id,p_data->req_data.trans_id,
p_data->req_data.status,NULL);
LOG_ERROR("Received button data:");
for(int i = 0; i < p_data->req_data.p_data->write_req.len; i++){
LOG_ERROR("%x",p_data->req_data.p_data->write_req.value[i]);
}
LOG_ERROR("\n");
if(p_data->req_data.p_data->write_req.handle == button_cb_env.button_inst.but_wirt_hdl){
p_rec_data = &p_data->req_data.p_data->write_req.value[0];
// button_msg_notify(len,p_rec_data);
(*p_inst->p_cback)(button_cb_env.button_inst.app_id,net_event,len,p_rec_data);
}
break;
case BTA_GATTS_CONF_EVT:
@ -285,9 +299,10 @@ BOOLEAN button_env_clcb_dealloc(UINT16 conn_id)
** Description Initializa the GATT Service for button profiles.
**
*******************************************************************************/
tGATT_STATUS button_init (void)
tGATT_STATUS button_init (tBU_CBACK *call_back)
{
tBT_UUID app_uuid = {LEN_UUID_16,{ATT_SVC_BUTTON}};
if(button_cb_env.enabled)
{
@ -299,6 +314,12 @@ tGATT_STATUS button_init (void)
memset(&button_cb_env,0,sizeof(tBUTTON_CB_ENV));
}
if(call_back != NULL)
{
button_cb_env.button_inst.p_cback = call_back;
}
/* register the button profile to the BTA_GATTS module*/
BTA_GATTS_AppRegister(&app_uuid,button_profile_cb);

Wyświetl plik

@ -34,11 +34,18 @@
#define BUT_MAX_STRING_DATA 7
typedef void (tBU_CBACK)(UINT8 app_id, UINT8 event, UINT8 len, UINT8 *data);
#ifndef BUT_MAX_INT_NUM
#define BUT_MAX_INT_NUM 4
#endif
enum
{
RECEIVE_NET_PASSWD_EVT,
RECEIVE_NET_SSD_EVT,
RECEIVE_EVT_MAX
};
/// button Service Attributes Indexes
enum
@ -79,6 +86,8 @@ typedef struct
UINT16 but_wirt_hdl;
UINT16 but_ntf_hdl;
UINT16 but_cfg_hdl;
tBU_CBACK *p_cback;
}tBUT_INST;
@ -102,7 +111,7 @@ UINT16 button_env_find_conn_id_by_bd_adddr(BD_ADDR bda);
BOOLEAN button_env_clcb_dealloc(UINT16 conn_id);
tGATT_STATUS button_init(void);
tGATT_STATUS button_init(tBU_CBACK *call_back);
void button_msg_notify(UINT8 len, UINT8 *button_msg);

@ -1 +1 @@
Subproject commit bcbc35215c6d87279da4b87a74d3360c537d6724
Subproject commit aa05c3fc82a7cb1cdcbe682b8973546ba016e202

Wyświetl plik

@ -20,12 +20,12 @@ config ESP32_DEFAULT_CPU_FREQ_MHZ
default 160 if ESP32_DEFAULT_CPU_FREQ_160
default 240 if ESP32_DEFAULT_CPU_FREQ_240
choice ESP32_WIFI_OR_BT
prompt "Select stack to enable (WiFi or BT)"
default ESP32_ENABLE_WIFI
help
Temporarily, WiFi and BT stacks can not be used at the same time.
Select which stack to enable.
#choice ESP32_WIFI_OR_BT
# prompt "Select stack to enable (WiFi or BT)"
# default ESP32_ENABLE_WIFI
# help
# Temporarily, WiFi and BT stacks can not be used at the same time.
# Select which stack to enable.
config ESP32_ENABLE_STACK_WIFI
bool "WiFi"
@ -34,9 +34,9 @@ config ESP32_ENABLE_STACK_BT
bool "BT"
select MEMMAP_BT if ESP32_ENABLE_STACK_BT
select BT_ENABLED if ESP32_ENABLE_STACK_BT
config ESP32_ENABLE_STACK_NONE
bool "None"
endchoice
#config ESP32_ENABLE_STACK_NONE
# bool "None"
#endchoice
config MEMMAP_BT
bool

Wyświetl plik

@ -0,0 +1,11 @@
#
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
# project subdirectory.
#
PROJECT_NAME := bluedroid_demos
COMPONENT_ADD_INCLUDEDIRS := components/include
include $(IDF_PATH)/make/project.mk

Wyświetl plik

@ -0,0 +1,10 @@
ESP-IDF Blufi demo
=======================
This is the demo for bluetooth config wifi connection to ap.
attentions:
1. Please use the BLEDEMO APK
2. As the GATTServer start a litte slowly, so Please Wait for a period, then use apk scan the apk util find a random address devices named Espressif_008
3. Just a unstable version..

Wyświetl plik

@ -0,0 +1,185 @@
/***************************************************************
* *
* * This file is for client to execute battery-related operation
* *
***************************************************************/
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
#include <stdio.h>
#include "bta_api.h"
#include "bta_gatt_api.h"
#include "controller.h"
#include "gatt_int.h"
#include "bt_trace.h"
#include "btm_api.h"
#include "bt_types.h"
#include "gattc_profile.h"
#define BT_BD_ADDR_STR "%02x:%02x:%02x:%02x:%02x:%02x"
#define BT_BD_ADDR_HEX(addr) addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]
tBTA_GATTC_IF client_if;
tBT_UUID bas_uuid = {LEN_UUID_16, {UUID_SERVCLASS_BATTERY}};
uint16_t get_uuid16(tBT_UUID* p_uuid)
{
if(p_uuid->len == LEN_UUID_16)
{
return p_uuid->uu.uuid16;
}
else if(p_uuid->len == LEN_UUID_128)
{
UINT16 u16;
UINT8 *p = &p_uuid->uu.uuid128[LEN_UUID_128 - 4];
STREAM_TO_UINT16(u16, p);
return u16;
}
else
{
return (UINT16)p_uuid->uu.uuid32;
}
}
/*fill a GATT ID structure*/
void bta_le_fill_16bits_gatt_id(UINT8 inst_id, UINT16 uuid, tBTA_GATT_ID* p_output)
{
p_output->inst_id = inst_id;
p_output->uuid.len = LEN_UUID_16;
p_output->uuid.uu.uuid16 = uuid;
}
/*fill a service ID structure with a 16 bits service UUID*/
void bta_le_fill_16bits_srvc_id(bool is_pri, UINT8 inst_id, UINT16 srvc_uuid, tBTA_GATT_SRVC_ID* p_output)
{
memset((void *)p_output, 0, sizeof(tBTA_GATT_SRVC_ID));
p_output->is_primary = is_pri;
bta_le_fill_16bits_gatt_id(inst_id, srvc_uuid, &p_output->id);
}
/*fill a char ID structure with a 16 bits char UUID*/
void bta_le_fill_16bits_char_id(UINT8 inst_id, UINT16 char_uuid, tBTA_GATT_ID* p_output)
{
memset((void *)p_output, 0, sizeof(tBTA_GATT_ID));
bta_le_fill_16bits_gatt_id(inst_id, char_uuid, p_output);
}
/******************************************************************************
** Function bas_gattc_callback
**
** Description battery service register callback function
*******************************************************************************/
static void bas_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data)
{
switch (event)
{
case BTA_GATTC_REG_EVT:
{
tBTA_GATT_STATUS status = p_data->reg_oper.status;
client_if = p_data->reg_oper.client_if;
LOG_ERROR("BAS register completed: event=%d, status=%d, client_if=%d\n",
event, status, client_if);
}
break;
/*connect callback*/
case BTA_GATTC_OPEN_EVT:
{
LOG_ERROR("\n%s:device is connected "BT_BD_ADDR_STR", client_if=%d, status=%d, connect_id=%d\n",
__FUNCTION__, BT_BD_ADDR_HEX(p_data->open.remote_bda), p_data->open.client_if,
p_data->open.status, p_data->open.conn_id);
/*return whether the remote device is currently connected*/
int is_connected = BTA_DmGetConnectionState(p_data->open.remote_bda);
LOG_ERROR("is_connected=%d\n",is_connected);
/*get the energy info of the controller*/
/*read battery level*/
int conn_id = p_data->open.conn_id;
/*discover service*/
BTA_GATTC_ServiceSearchRequest(conn_id, NULL);
}
break;
case BTA_GATTC_SEARCH_RES_EVT:
{
// tBTA_GATTC_SRVC_RES service_result;
LOG_ERROR("find the service,uuid=0x%x, is_primary=%d\n",
get_uuid16(&p_data->srvc_res.service_uuid.id.uuid),
p_data->srvc_res.service_uuid.is_primary);
}
break;
case BTA_GATTC_SEARCH_CMPL_EVT:
{
LOG_ERROR("search service complete, conn_id=%d,status=%d\n", p_data->search_cmpl.conn_id,
p_data->search_cmpl.status);
/*get first characteristic of battey service*/
LOG_ERROR("get first characteristic of battery service\n");
tBTA_GATT_STATUS status;
tBTA_GATT_SRVC_ID battery_srvc_id;
tBTA_GATTC_CHAR_ID out_char_id;
tGATT_CHAR_PROP out_char_prop;
bta_le_fill_16bits_srvc_id(TRUE, 0, UUID_SERVCLASS_BATTERY, &battery_srvc_id);
status = BTA_GATTC_GetFirstChar(p_data->search_cmpl.conn_id, &battery_srvc_id, NULL,
&out_char_id, &out_char_prop);
if(status == 0)
{
LOG_ERROR("the first char:srvc_id=0x%x,char_id=0x%x, property = %d\n",
get_uuid16(&out_char_id.srvc_id.id.uuid), get_uuid16(&out_char_id.char_id.uuid),
out_char_prop);
/*read battery level*/
tBTA_GATTC_CHAR_ID battery_char_id;
bta_le_fill_16bits_srvc_id(TRUE, 0, UUID_SERVCLASS_BATTERY, &battery_char_id.srvc_id);
bta_le_fill_16bits_char_id(0, GATT_UUID_BATTERY_LEVEL, &battery_char_id.char_id);
BTA_GATTC_ReadCharacteristic(p_data->search_cmpl.conn_id, &battery_char_id,
BTA_GATT_AUTH_REQ_NONE);
}
}
break;
case BTA_GATTC_READ_CHAR_EVT:
{
LOG_ERROR("\nread characteristic:connect_id=%d, status=%d\n",
p_data->read.conn_id, p_data->read.status);
LOG_ERROR("srvc_id=0x%x,char_id=0x%x,descr_type=0x%x\n",
get_uuid16(&p_data->read.srvc_id.id.uuid),
get_uuid16(&p_data->read.char_id.uuid),
get_uuid16(&p_data->read.descr_type.uuid));
if(get_uuid16(&p_data->read.descr_type.uuid) != GATT_UUID_CHAR_AGG_FORMAT
&& p_data->read.p_value->unformat.len > 0
&& p_data->read.p_value->unformat.p_value != NULL)
{
LOG_ERROR("read the value: len=%d, value=%d\n", p_data->read.p_value->unformat.len,
*(p_data->read.p_value->unformat.p_value));
}
}
break;
default:
LOG_ERROR("unsettled event: %d\n", event);
}
}
/***************************************************************
**
** Function bac_register
**
** Description register app for battery service
**
****************************************************************/
void bac_register(void)
{
BTA_GATTC_AppRegister(&bas_uuid, bas_gattc_callback);
}

Wyświetl plik

@ -0,0 +1,186 @@
/**
****************************************************************************************
*
* @file bt_app.c
*
* @brief Application entry point
*
* Copyright (C) Espressif 2016
* Created by Yulong at 2016/9/9
*
*
****************************************************************************************
*/
#include "bt_app_defs.h"
/*******************************************************************************
**
** Function ESP_AppConfigadvData
**
** Description This function is called to override the BTA default ADV parameters.
**
** adv_data: Pointer to User defined ADV data structure. This
** memory space can not be freed until p_adv_data_cback
** is received.
** p_adv_data_cback: set adv data complete callback.
**
** Returns None
**
*******************************************************************************/
void ESP_AppBleConfigadvData(tESP_BLE_ADV_DATA *adv_data,
tBTA_SET_ADV_DATA_CMPL_CBACK *p_adv_data_cback)
{
tBTA_BLE_AD_MASK data_mask = 0;
if(adv_data->adv_name != NULL)
{
data_mask |= BTM_BLE_AD_BIT_DEV_NAME;
BTA_DmSetDeviceName(adv_data->adv_name);
}
if(adv_data->ble_adv_data.int_range.low != 0 ||
adv_data->ble_adv_data.int_range.hi != 0)
data_mask |= BTM_BLE_AD_BIT_INT_RANGE;
if(adv_data->ble_adv_data.p_manu != NULL)
{
data_mask |= BTM_BLE_AD_BIT_MANU;
}
if(adv_data->ble_adv_data.p_services != NULL)
{
data_mask |= BTM_BLE_AD_BIT_SERVICE;
}
if(adv_data->ble_adv_data.p_service_32b != NULL)
{
data_mask |= BTM_BLE_AD_BIT_SERVICE_32;
}
if(adv_data->ble_adv_data.p_services_128b != NULL)
{
data_mask |= BTM_BLE_AD_BIT_SERVICE_128;
}
if(adv_data->ble_adv_data.p_sol_services != NULL)
{
data_mask |= BTM_BLE_AD_BIT_SERVICE_SOL;
}
if(adv_data->ble_adv_data.p_sol_service_32b != NULL)
{
data_mask |= BTM_BLE_AD_BIT_SERVICE_32SOL;
}
if(adv_data->ble_adv_data.p_sol_service_128b != NULL)
{
data_mask |= BTM_BLE_AD_BIT_SERVICE_128SOL;
}
if(adv_data->ble_adv_data.p_service_data != NULL)
{
data_mask |= BTM_BLE_AD_BIT_SERVICE_DATA;
}
if(adv_data->ble_adv_data.appearance != 0)
{
data_mask |= BTM_BLE_AD_BIT_APPEARANCE;
}
if(adv_data->ble_adv_data.p_proprietary != NULL)
{
data_mask |= BTM_BLE_AD_BIT_PROPRIETARY;
}
if(adv_data->ble_adv_data.tx_power != 0)
{
data_mask |= BTM_BLE_AD_BIT_TX_PWR;
}
BTA_DmBleSetAdvConfig(data_mask, &(adv_data->ble_adv_data), p_adv_data_cback);
}
/*******************************************************************************
**
** Function ESP_BleSetScanRsp
**
** Description This function is called to override the app scan response.
**
** Parameters Pointer to User defined ADV data structure
**
** Returns None
**
*******************************************************************************/
void ESP_AppBleSetScanRsp(tESP_BLE_ADV_DATA *scan_rsp_data,
tBTA_SET_ADV_DATA_CMPL_CBACK *p_scan_rsp_data_cback)
{
tBTA_BLE_AD_MASK data_mask = 0;
if(scan_rsp_data->adv_name != NULL)
{
data_mask |= BTM_BLE_AD_BIT_DEV_NAME;
BTA_DmSetDeviceName(scan_rsp_data->adv_name);
}
if(scan_rsp_data->ble_adv_data.int_range.low != 0 ||
scan_rsp_data->ble_adv_data.int_range.hi != 0)
data_mask |= BTM_BLE_AD_BIT_INT_RANGE;
if(scan_rsp_data->ble_adv_data.p_manu != NULL)
{
data_mask |= BTM_BLE_AD_BIT_MANU;
}
if(scan_rsp_data->ble_adv_data.p_services != NULL)
{
data_mask |= BTM_BLE_AD_BIT_SERVICE;
}
if(scan_rsp_data->ble_adv_data.p_service_32b != NULL)
{
data_mask |= BTM_BLE_AD_BIT_SERVICE_32;
}
if(scan_rsp_data->ble_adv_data.p_services_128b != NULL)
{
data_mask |= BTM_BLE_AD_BIT_SERVICE_128;
}
if(scan_rsp_data->ble_adv_data.p_sol_services != NULL)
{
data_mask |= BTM_BLE_AD_BIT_SERVICE_SOL;
}
if(scan_rsp_data->ble_adv_data.p_sol_service_32b != NULL)
{
data_mask |= BTM_BLE_AD_BIT_SERVICE_32SOL;
}
if(scan_rsp_data->ble_adv_data.p_sol_service_128b != NULL)
{
data_mask |= BTM_BLE_AD_BIT_SERVICE_128SOL;
}
if(scan_rsp_data->ble_adv_data.p_service_data != NULL)
{
data_mask |= BTM_BLE_AD_BIT_SERVICE_DATA;
}
if(scan_rsp_data->ble_adv_data.appearance != 0)
{
data_mask |= BTM_BLE_AD_BIT_APPEARANCE;
}
if(scan_rsp_data->ble_adv_data.p_proprietary != NULL)
{
data_mask |= BTM_BLE_AD_BIT_PROPRIETARY;
}
if(scan_rsp_data->ble_adv_data.tx_power != 0)
{
data_mask |= BTM_BLE_AD_BIT_TX_PWR;
}
BTA_DmBleSetScanRsp(data_mask, &(scan_rsp_data->ble_adv_data), p_scan_rsp_data_cback);
}

Wyświetl plik

@ -0,0 +1,387 @@
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
#include "fixed_queue.h"
#include "gki.h"
#include "bt_defs.h"
#include "bt_trace.h"
#include "bt_types.h"
#include "allocator.h"
#include "bta_api.h"
#include "bta_gatt_api.h"
#include "bt_app_common.h"
#include "controller.h"
#include "hash_map.h"
#include "hash_functions.h"
#include "alarm.h"
#include "app_button.h"
#include "button_pro.h"
#include "thread.h"
#include "bt_app_common.h"
#include "dis_api.h"
#include "gattc_profile.h"
#include "smp_int.h"
#include "smp_api.h"
static fixed_queue_t *bta_app_msg_queue;
fixed_queue_t *bt_app_general_alarm_queue;
hash_map_t *bt_app_general_alarm_hash_map;
pthread_mutex_t bt_app_general_alarm_lock;
static const size_t BT_APP_GENERAL_ALARM_HASH_MAP_SIZE = 10;
xQueueHandle xBtaApp1Queue;
xTaskHandle xBtaApp1TaskHandle;
#define BT_APP_TTYPE_MAIN_ENTRY (1)
static TIMER_LIST_ENT main_boot_tle;
tSMP_CB smp_cmd;
static void bt_app_context_switched(void *p_msg);
static void bt_app_send_msg(void *p_msg);
static void bt_app_task_handler(void *arg);
static void bta_app_msg_ready(fixed_queue_t *queue);
static void bt_app_general_alarm_ready(fixed_queue_t *queue);
static void bt_app_general_alarm_process(TIMER_LIST_ENT *p_tle);
void bt_app_start_timer(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout_sec);
//extern void ble_test_conn(void);
//extern void bt_test_start_inquiry(void);
extern void ble_server_test(void);
static void bt_app_task_handler(void *arg)
{
TaskEvt_t *e;
UINT8 button_msg[2] = {0x01,0x00};
for (;;) {
if (pdTRUE == xQueueReceive(xBtaApp1Queue, &e, (portTickType)portMAX_DELAY)) {
if (e->sig == 0xff) {
fixed_queue_process(bta_app_msg_queue);
fixed_queue_process(bt_app_general_alarm_queue);
}else if(e->sig == BUTTON_PRESS_EVT){
LOG_ERROR("button_press_event come in,button_value=%x\n",e->par);
button_msg[1] = e->par;
button_msg_notify(2,button_msg);
}
}
osi_free(e);
}
}
static void bt_app_task_post(void)
{
TaskEvt_t *evt = (TaskEvt_t *)osi_malloc(sizeof(TaskEvt_t));
if (evt == NULL)
return;
evt->sig = 0xff;
evt->par = 0;
if (xQueueSend(xBtaApp1Queue, &evt, 10/portTICK_RATE_MS) != pdTRUE) {
ets_printf("btdm_post failed\n");
}
}
static void bta_app_msg_ready(fixed_queue_t *queue) {
BT_HDR *p_msg;
while (!fixed_queue_is_empty(queue)) {
p_msg = (BT_HDR *)fixed_queue_dequeue(queue);
LOG_ERROR("bta_app_msg_ready, evt: %d\n", p_msg->event);
switch (p_msg->event) {
case BT_EVT_APP_CONTEXT_SWITCH:
bt_app_context_switched(p_msg);
break;
default:
LOG_ERROR("unhandled BT_APP event (%d)\n", p_msg->event & BT_EVT_MASK);
break;
}
GKI_freebuf(p_msg);
}
}
static void bt_app_context_switched(void *p_msg)
{
tBTAPP_CONTEXT_SWITCH_CBACK *p = (tBTAPP_CONTEXT_SWITCH_CBACK *) p_msg;
if (p->p_cb)
p->p_cb(p->event, p->p_param);
}
static void bt_app_send_msg(void *p_msg)
{
if (bta_app_msg_queue) {
fixed_queue_enqueue(bta_app_msg_queue, p_msg);
//ke_event_set(KE_EVENT_BT_APP_TASK);
bt_app_task_post();
}
}
bt_status_t bt_app_transfer_context (tBTAPP_CBACK *p_cback, UINT16 event, char* p_params, int param_len, tBTAPP_COPY_CBACK *p_copy_cback)
{
tBTAPP_CONTEXT_SWITCH_CBACK *p_msg;
LOG_ERROR("btapp_transfer_context evt %d, len %d", event, param_len);
/* allocate and send message that will be executed in btif context */
if ((p_msg = (tBTAPP_CONTEXT_SWITCH_CBACK *) GKI_getbuf(sizeof(tBTAPP_CONTEXT_SWITCH_CBACK) + param_len)) != NULL)
{
p_msg->hdr.event = BT_EVT_APP_CONTEXT_SWITCH; /* internal event */
p_msg->p_cb = p_cback;
p_msg->event = event; /* callback event */
/* check if caller has provided a copy callback to do the deep copy */
if (p_copy_cback)
{
p_copy_cback(event, p_msg->p_param, p_params);
}
else if (p_params)
{
memcpy(p_msg->p_param, p_params, param_len); /* callback parameter data */
}
bt_app_send_msg(p_msg);
return BT_STATUS_SUCCESS;
}
else
{
/* let caller deal with a failed allocation */
return BT_STATUS_NOMEM;
}
}
void bt_app_task_shut_down(void)
{
fixed_queue_unregister_dequeue(bta_app_msg_queue);
fixed_queue_free(bta_app_msg_queue, NULL);
bta_app_msg_queue = NULL;
// todo: hash map, pthread_mutex...
fixed_queue_unregister_dequeue(bt_app_general_alarm_queue);
vTaskDelete(xBtaApp1TaskHandle);
vTaskDelete(xBtaApp1Queue);
}
void bt_app_task_start_up(void)
{
bta_app_msg_queue = fixed_queue_new(SIZE_MAX);
if (bta_app_msg_queue == NULL)
goto error_exit;
//ke_event_callback_set(KE_EVENT_BT_APP_TASK, &bt_app_task_handler);
xBtaApp1Queue = xQueueCreate(3, sizeof(void *));
xTaskCreate(bt_app_task_handler, "BtaApp1T", 8192, NULL, configMAX_PRIORITIES - 3, xBtaApp1TaskHandle);
fixed_queue_register_dequeue(bta_app_msg_queue, bta_app_msg_ready);
bt_app_general_alarm_hash_map = hash_map_new(BT_APP_GENERAL_ALARM_HASH_MAP_SIZE,
hash_function_pointer, NULL, (data_free_fn)osi_alarm_free, NULL);
if (bt_app_general_alarm_hash_map == NULL)
goto error_exit;
pthread_mutex_init(&bt_app_general_alarm_lock, NULL);
bt_app_general_alarm_queue = fixed_queue_new(SIZE_MAX);
if (bt_app_general_alarm_queue == NULL)
goto error_exit;
fixed_queue_register_dequeue(bt_app_general_alarm_queue, bt_app_general_alarm_ready);
memset(&main_boot_tle, 0, sizeof(TIMER_LIST_ENT));
return;
error_exit:
LOG_ERROR("%s Unable to allocate resources for bt_app", __func__);
bt_app_task_shut_down();
}
static void bt_app_dm_data_copy(uint16_t event, char *dst, char *src)
{
tBTA_DM_SEC *dst_dm_sec = (tBTA_DM_SEC*)dst;
tBTA_DM_SEC *src_dm_sec = (tBTA_DM_SEC*)src;
if (!src_dm_sec)
return;
assert(dst_dm_sec);
memcpy(dst_dm_sec, src_dm_sec, sizeof(tBTA_DM_SEC));
if (event == BTA_DM_BLE_KEY_EVT)
{
dst_dm_sec->ble_key.p_key_value = osi_malloc(sizeof(tBTM_LE_KEY_VALUE));
assert(src_dm_sec->ble_key.p_key_value);
assert(dst_dm_sec->ble_key.p_key_value);
memcpy(dst_dm_sec->ble_key.p_key_value, src_dm_sec->ble_key.p_key_value, sizeof(tBTM_LE_KEY_VALUE));
}
}
static void bt_app_dm_data_free(uint16_t event, tBTA_DM_SEC *dm_sec)
{
if (event == BTA_DM_BLE_KEY_EVT)
osi_free(dm_sec->ble_key.p_key_value);
}
static void bt_app_dm_upstreams_evt(UINT16 event, char *p_param)
{
tBTA_DM_SEC *p_data = (tBTA_DM_SEC*)p_param;
switch (event) {
case BTA_DM_ENABLE_EVT: {
// BTA_DmSetDeviceName("ijiazu");
/*set connectable,discoverable, pairable and paired only modes of local device*/
tBTA_DM_DISC disc_mode = BTA_DM_GENERAL_DISC | BTA_DM_BLE_GENERAL_DISCOVERABLE;
tBTA_DM_CONN conn_mode = BTA_DM_CONN | BTA_DM_BLE_CONNECTABLE;
BTA_DmSetVisibility(disc_mode, conn_mode, BTA_DM_IGNORE, BTA_DM_IGNORE);
#if (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
/* Enable local privacy */
BTA_DmBleConfigLocalPrivacy(BLE_LOCAL_PRIVACY_ENABLED);
do {
const controller_t *controller = controller_get_interface();
char bdstr[18];
bdaddr_to_string(controller->get_address(), bdstr, sizeof(bdstr));
LOG_ERROR("BDA is: %s\n", bdstr);
} while (0);
#endif
}
break;
case BTA_DM_BLE_SEC_REQ_EVT:
smp_cmd.local_io_capability = 0x03; //no input no output
smp_cmd.loc_oob_flag = 0x00; //oob data not present
smp_cmd.loc_auth_req = 0x05;
smp_cmd.loc_enc_size = 0x10;
smp_cmd.local_i_key = 0x07;
smp_cmd.local_r_key = 0x07;
memcpy(smp_cmd.pairing_bda,p_data->ble_req.bd_addr,0x06);
smp_send_cmd(SMP_OPCODE_PAIRING_RSP,&smp_cmd);
smp_set_state(SMP_STATE_WAIT_CONFIRM);
//BTA_DmConfirm(p_data->ble_req.bd_addr,true);
break;
default:
break;
}
bt_app_dm_data_free(event, p_data);
}
static void bte_dm_evt(tBTA_DM_SEC_EVT event, tBTA_DM_SEC* p_data)
{
LOG_ERROR("bte_dm_evt: %d\n", (uint16_t)event);
bt_app_transfer_context(bt_app_dm_upstreams_evt, (uint16_t)event,
(void *)p_data, sizeof(tBTA_DM_SEC), bt_app_dm_data_copy);
}
void bt_app_init_ok(UNUSED_ATTR uint16_t event, UNUSED_ATTR char *p_param)
{
BTA_EnableBluetooth(bte_dm_evt);
vTaskDelay(1000 / portTICK_PERIOD_MS);
bt_app_start_timer(&main_boot_tle, BT_APP_TTYPE_MAIN_ENTRY, 8);
}
/* Alarm timer */
static void bt_app_general_alarm_cb(void *data) {
assert(data != NULL);
TIMER_LIST_ENT *p_tle = (TIMER_LIST_ENT *)data;
fixed_queue_enqueue(bt_app_general_alarm_queue, p_tle);
//ke_event_set(KE_EVENT_BT_APP_TASK);
bt_app_task_post();
}
void bt_app_start_timer(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout_sec) {
osi_alarm_t *alarm = NULL;
assert(p_tle != NULL);
// Get the alarm for the timer list entry.
pthread_mutex_lock(&bt_app_general_alarm_lock);
if (!hash_map_has_key(bt_app_general_alarm_hash_map, p_tle)) {
alarm = osi_alarm_new("bt_app", bt_app_general_alarm_cb, (void *)p_tle, 0);
hash_map_set(bt_app_general_alarm_hash_map, p_tle, alarm);
}
pthread_mutex_unlock(&bt_app_general_alarm_lock);
pthread_mutex_lock(&bt_app_general_alarm_lock);
alarm = hash_map_get(bt_app_general_alarm_hash_map, p_tle);
pthread_mutex_unlock(&bt_app_general_alarm_lock);
if (alarm == NULL) {
LOG_ERROR("%s Unable to create alarm", __func__);
return;
}
osi_alarm_cancel(alarm);
p_tle->event = type;
// NOTE: This value is in seconds but stored in a ticks field.
p_tle->ticks = timeout_sec;
p_tle->in_use = TRUE;
osi_alarm_set(alarm, (period_ms_t)(timeout_sec * 1000));
}
void bt_app_stop_timer(TIMER_LIST_ENT *p_tle)
{
assert(p_tle != NULL);
if (p_tle->in_use == FALSE)
return;
p_tle->in_use = FALSE;
// Get the alarm for the timer list entry.
osi_alarm_t *alarm = hash_map_get(bt_app_general_alarm_hash_map, p_tle);
if (alarm == NULL) {
LOG_WARN("%s Unable to find expected alarm in hashmap", __func__);
return;
}
osi_alarm_cancel(alarm);
}
static void bt_app_general_alarm_process(TIMER_LIST_ENT *p_tle)
{
assert(p_tle != NULL);
LOG_ERROR("general_alarm_process\n");
switch (p_tle->event) {
case BT_APP_TTYPE_MAIN_ENTRY:
LOG_ERROR("BT_APP main boot**********\n");
// ble_test_conn();
// ble_server_test();
// bt_test_start_inquiry();
gatts_server_test();
//gattc_client_test();
break;
}
}
static void bt_app_general_alarm_ready(fixed_queue_t *queue)
{
TIMER_LIST_ENT *p_tle;
while (!fixed_queue_is_empty(queue)) {
p_tle = (TIMER_LIST_ENT *)fixed_queue_dequeue(queue);
bt_app_general_alarm_process(p_tle);
}
}
void bt_app_core_start(void) {
bt_app_transfer_context(bt_app_init_ok, 0, NULL, 0, NULL);
}

Wyświetl plik

@ -0,0 +1,225 @@
/**
*******************************************************************************
*********
*
* @file app_button.c
*
* @brief button Service Application entry point
*
* Copyright (C) ESPRESSSIF 2016
* Created by Yulong at 2016/08/24
*
*
*******************************************************************************
*********
*/
#if 0
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
#include <stdio.h>
#include "rom/gpio.h"
#include "app_button.h"
#include "bt_trace.h"
#include "freertos/FreeRTOS.h"
#include "freertos/timers.h"
#include "freertos/task.h"
#include "freertos/xtensa_api.h"
#include "thread.h"
#include "allocator.h"
#include "button_pro.h"
#define GPIO_INUM 8
#define TABLE_ELEMENT_CNT(table) ((sizeof(table))/(sizeof(table[0])));
app_key_env key_press;
uint8_t gpio_test_table[]={0,2,4,5,12,13,14,15,16,17,18,19,20,21,22,23,25,26,27,33,34,35,36,37,38,39};
struct gpio_test_info{
uint8_t *gpio_test_table;
uint8_t gpio_test_num;
void *time_s;
};
static void gpio_irq_init(uint64_t gpio_num);
void gpio_check_register(enum_gpio_num_t gpio_num)
{
if(gpio_num>=GPIO_PIN_COUNT||0==GPIO_PIN_MUX_REG[gpio_num]){
ets_printf("io_num=%d not exits\n",gpio_num);
return;
}
LOG_ERROR("---------gpio_num %d reg----------\n",gpio_num);
LOG_ERROR("GPIO_IOMUX_%d=0x%08x\n",gpio_num,READ_PERI_REG(GPIO_PIN_MUX_REG[gpio_num]));
LOG_ERROR("GPIO_PIN%d_ADDR=0x%08x\n",gpio_num,READ_PERI_REG(GPIO_PIN_ADDR(gpio_num)));
LOG_ERROR("GPIO_OUT_REG=0x%08x\n",READ_PERI_REG(GPIO_OUT_REG));
LOG_ERROR("GPIO_OUT1_REG=0x%08x\n",READ_PERI_REG(GPIO_OUT1_REG));
LOG_ERROR("GPIO_ENABLE_REG=0x%08x\n",READ_PERI_REG(GPIO_ENABLE_REG));
LOG_ERROR("GPIO_ENABLE1_REG=0x%08x\n",READ_PERI_REG(GPIO_ENABLE1_REG));
LOG_ERROR("GPIO_IN_REG=0x%08x\n",READ_PERI_REG(GPIO_IN_REG));
LOG_ERROR("GPIO_IN1_REG=0x%08x\n",READ_PERI_REG(GPIO_IN1_REG));
LOG_ERROR("GPIO_STATUS_REG=0x%08x\n",READ_PERI_REG(GPIO_STATUS_REG));
LOG_ERROR("GPIO_STATUS1_REG=0x%08x\n",READ_PERI_REG(GPIO_STATUS1_REG));
}
void t1_callback(void *arg)
{
static uint8_t level=0;
static uint8_t cnt=0;
uint8_t err_flag=0;
struct gpio_test_info *gpio_test=(struct gpio_test_info*)(arg);
uint8_t i=0;
while(1){
gpio_check_register(35);
vTaskDelay(2*1000);
/*
level=~level;
LOG_ERROR("Test cnt %u, level %u\n",cnt+1,level&0x01);
for(i=0;i<gpio_test->gpio_test_num;i++){
gpio_set_output_level(gpio_test->gpio_test_table[i],level&0x01);
if(gpio_get_input_level(gpio_test->gpio_test_table[i])!=(level&0x01))
{
err_flag=1;
LOG_ERROR("[ERR] GPIO%u set_level %u get_level %u\n",gpio_test->gpio_test_table[i],level&0x01,gpio_get_input_level(gpio_test->gpio_test_table[i]));
}
else{
LOG_ERROR("GPIO%u OK\n",gpio_test->gpio_test_table[i]);
}
}
cnt++;
if(err_flag==0){
LOG_ERROR("cnt %u test ok\n",cnt);
}
err_flag=0;
if(cnt>=10){
LOG_ERROR("Gpio input and output test end\n");
vTaskDelete(NULL);*/
// }
//vTaskDelay(2*1000);
}
}
void app_button_init(void)
{
uint64_t gpio_num = GPIO_Pin_27|GPIO_Pin_35|GPIO_Pin_34|GPIO_Pin_36|GPIO_Pin_39;
// Reset environment
memset(&key_press, 0, sizeof(key_press));
gpio_irq_init(gpio_num);
static struct gpio_test_info gpio_test_infor;
LOG_ERROR("app_button_init.");
/* TimerHandle_t t1=NULL;
t1=xTimerCreate("t1_time",(1000/portTICK_PERIOD_MS),pdTRUE,&gpio_test_infor,t1_callback);
do{
gpio_test_infor.gpio_test_table=gpio_test_table;
gpio_test_infor.gpio_test_num=TABLE_ELEMENT_CNT(gpio_test_table);
gpio_test_infor.time_s=t1;
}while(0);*/
// xTaskCreate(t1_callback,"t1_callback",1024,&gpio_test_infor,30,NULL);
LOG_ERROR("gpio_input_output_demo\n");
return;
}
static void gpio_irq_init(uint64_t gpio_num)
{
gpio_config_t gpio_config_prot;
memset(&gpio_config_prot,0,sizeof(gpio_config_prot));
gpio_config_prot.GPIO_Pin= gpio_num;
gpio_config_prot.GPIO_Mode=GPIO_Mode_Input;
gpio_config_prot.GPIO_IntrType=GPIO_PIN_INTR_NEGEDGE;
gpio_config_prot.GPIO_Pullup=GPIO_PullUp_EN;
gpio_config_prot.GPIO_Pulldown=GPIO_PullDown_DIS;
gpio_config(&gpio_config_prot);
//Register gpio handler
gpio_intr_handler_register(GPIO_isr_callback,NULL);
//Enable gpio intr
xt_ints_on(1<<GPIO_INUM);
//ETS_GPIO_INTR_ENABLE(); //Enable intr
}
void GPIO_isr_callback(void* arg)
{
/*GPIO interrupt process*/
uint32_t gpio_intr_status = 0;
uint32_t gpio_intr_status_h = 0;
uint32_t gpio_num =0;
//disable the pending interrupt
xt_ints_off(1<<GPIO_INUM);
gpio_intr_status = READ_PERI_REG(GPIO_STATUS_REG);
gpio_intr_status_h = READ_PERI_REG(GPIO_STATUS1_REG);
LOG_ERROR("the interrupt come in,gpio_intr_staus = %d,gpio_intr_status_h=%d\n",gpio_intr_status,gpio_intr_status_h);
//clear intr for gpio0-gpio31
WRITE_PERI_REG((GPIO_STATUS_W1TC_REG),(READ_PERI_REG(GPIO_STATUS_W1TC_REG)|(gpio_intr_status)));
//clear intr for gpio32-39
WRITE_PERI_REG((GPIO_STATUS1_W1TC_REG),(READ_PERI_REG(GPIO_STATUS1_W1TC_REG)|(gpio_intr_status_h)));
do{
if(gpio_num < 32){
if(gpio_intr_status&BIT(gpio_num))
{
LOG_ERROR("Intr GPIO= %d\n",gpio_num);
break;
}
}
else{
if(gpio_intr_status_h&BIT(gpio_num - 32)){
LOG_ERROR("Intr GPIO = %d\n",gpio_num);
break;
}
}
}while(++gpio_num<GPIO_PIN_COUNT);
TaskEvt_t *evt = (TaskEvt_t *)osi_malloc(sizeof(TaskEvt_t));
if(evt == NULL)
{
return;
}
switch(gpio_num)
{
case GPIO_NUM_35:
evt->par = Button_Voice;
break;
case GPIO_NUM_34:
evt->par = Button_OK;
break;
case GPIO_NUM_39:
evt->par = Button_Down;
break;
case GPIO_NUM_36:
evt->par = Button_Up;
break;
default:
evt->par = Button_Back;
break;
}
evt->sig = BUTTON_PRESS_EVT;
if(xQueueSend(xBtaApp1Queue,&evt,10/portTICK_RATE_MS)!=pdTRUE){
LOG_ERROR("btdm_post_failed\n");
}
//enable the interrupt
xt_ints_on(1<<GPIO_INUM);
LOG_ERROR("the interrupt come in arg = %s\n",arg);
}
uint8_t check_sum(uint8_t *check_array,uint8_t len)
{
uint8_t i,sum = 0;
for(i = 0;i < len; i++)
{
sum ^= check_array[i];
}
sum += 1;
return sum;
}
#endif

Wyświetl plik

@ -0,0 +1,381 @@
/****************************************************************************
*
* This file is for gatt client. It can scan ble device, connect one device,
*
****************************************************************************/
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
#include <stdio.h>
#include "bta_api.h"
#include "bta_gatt_api.h"
#include "controller.h"
#include "bt_trace.h"
#include "btm_api.h"
#include "bt_types.h"
#include "gattc_profile.h"
#define BT_BD_ADDR_STR "%02x:%02x:%02x:%02x:%02x:%02x"
#define BT_BD_ADDR_HEX(addr) addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]
tBTA_GATTC_IF client_if;
BD_ADDR obj_addr;
static unsigned char BASE_UUID[16] = {
0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
typedef struct {
uint8_t uu[16];
} bt_uuid_t;
int uuidType(unsigned char* p_uuid)
{
int i = 0;
int match = 0;
int all_zero = 1;
for(i = 0; i != 16; ++i)
{
if (i == 12 || i == 13)
continue;
if (p_uuid[i] == BASE_UUID[i])
++match;
if (p_uuid[i] != 0)
all_zero = 0;
}
if (all_zero)
return 0;
if (match == 12)
return LEN_UUID_32;
if (match == 14)
return LEN_UUID_16;
return LEN_UUID_128;
}
static void btif_to_bta_uuid(tBT_UUID *p_dest, bt_uuid_t *p_src)
{
char *p_byte = (char*)p_src;
int i = 0;
p_dest->len = uuidType(p_src->uu);
switch (p_dest->len)
{
case LEN_UUID_16:
p_dest->uu.uuid16 = (p_src->uu[13] << 8) + p_src->uu[12];
break;
case LEN_UUID_32:
p_dest->uu.uuid32 = (p_src->uu[13] << 8) + p_src->uu[12];
p_dest->uu.uuid32 += (p_src->uu[15] << 24) + (p_src->uu[14] << 16);
break;
case LEN_UUID_128:
for(i = 0; i != 16; ++i)
p_dest->uu.uuid128[i] = p_byte[i];
break;
default:
LOG_ERROR("%s: Unknown UUID length %d!", __FUNCTION__, p_dest->len);
break;
}
}
/*
uint16_t get_uuid16(tBT_UUID* p_uuid)
{
if(p_uuid->len == LEN_UUID_16)
{
return p_uuid->uu.uuid16;
}
else if(p_uuid->len == LEN_UUID_128)
{
UINT16 u16;
UINT8 *p = &p_uuid->uu.uuid128[LEN_UUID_128 - 4];
STREAM_TO_UINT16(u16, p);
return u16;
}
else
{
return (UINT16)p_uuid->uu.uuid32;
}
}
//fill a GATT ID structure
void bta_le_fill_16bits_gatt_id(UINT8 inst_id, UINT16 uuid, tBTA_GATT_ID* p_output)
{
p_output->inst_id = inst_id;
p_output->uuid.len = LEN_UUID_16;
p_output->uuid.uu.uuid16 = uuid;
}
//fill a service ID structure with a 16 bits service UUID
void bta_le_fill_16bits_srvc_id(bool is_pri, UINT8 inst_id, UINT16 srvc_uuid, tBTA_GATT_SRVC_ID* p_output)
{
memset((void *)p_output, 0, sizeof(tBTA_GATT_SRVC_ID));
p_output->is_primary = is_pri;
bta_le_fill_16bits_gatt_id(inst_id, srvc_uuid, &p_output->id);
}
//fill a char ID structure with a 16 bits char UUID
void bta_le_fill_16bits_char_id(UINT8 inst_id, UINT16 char_uuid, tBTA_GATT_ID* p_output)
{
memset((void *)p_output, 0, sizeof(tBTA_GATT_ID));
bta_le_fill_16bits_gatt_id(inst_id, char_uuid, p_output);
}
*/
/*get remote name*/
static bool check_remote_name(tBTA_DM_INQ_RES* result, uint8_t* rmt_name, uint8_t* rmt_name_len)
{
uint8_t *p_rmt_name = NULL;
uint8_t remote_name_len = 0;
if (result->p_eir) {
p_rmt_name = BTM_CheckEirData(result->p_eir,
BTM_EIR_COMPLETE_LOCAL_NAME_TYPE,
&remote_name_len);
if (!p_rmt_name)
p_rmt_name = BTM_CheckEirData(result->p_eir,
BTM_EIR_SHORTENED_LOCAL_NAME_TYPE,
&remote_name_len);
if (p_rmt_name) {
if (remote_name_len > BD_NAME_LEN)
remote_name_len = BD_NAME_LEN;
if (rmt_name && rmt_name_len) {
memcpy(rmt_name, p_rmt_name, remote_name_len);
*(rmt_name + remote_name_len) = 0;
*rmt_name_len = remote_name_len;
}
return true;
}
}
return false;
}
/************************************************************************************
* * Function bta_scan_recult_callback
* *
* * Description scan result.it will be called when device scaned a peer device
* *
* * Return NULL
**************************************************************************************/
static void bta_scan_result_callback(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH* p_data)
{
uint8_t len;
BD_ADDR bd_addr;
char dev_name[32];
tBTA_GATT_TRANSPORT transport = BTA_GATT_TRANSPORT_LE;
//char obj_name[] = "Find Me";
char obj_name[] = "SimpleBLEPeripheral";
uint8_t dev_name_len;
switch (event)
{
case BTA_DM_INQ_RES_EVT:
{
LOG_ERROR("scan result: event=%d, "BT_BD_ADDR_STR", device_type=%d\n",
event, BT_BD_ADDR_HEX(p_data->inq_res.bd_addr), p_data->inq_res.device_type);
bdcpy(bd_addr, p_data->inq_res.bd_addr);
if (p_data->inq_res.p_eir)
{
if (BTM_CheckEirData(p_data->inq_res.p_eir, BTM_EIR_COMPLETE_LOCAL_NAME_TYPE, &len))
{
p_data->inq_res.remt_name_not_required = TRUE;
}
}
if(check_remote_name(&(p_data->inq_res), dev_name, &dev_name_len))
{
LOG_ERROR("scan device name len=%d, name = %s\n", dev_name_len, dev_name);
}
if(strcmp(dev_name, obj_name) == 0)
{
bdcpy(obj_addr, bd_addr);
LOG_ERROR("find the device, obj_addr="BT_BD_ADDR_STR"\n", BT_BD_ADDR_HEX(obj_addr));
// BTA_GATTC_Open(client_if, obj_addr, true, transport);
}
}
break;
case BTA_DM_INQ_CMPL_EVT:
{
LOG_ERROR("%s-BLE observe complete. Num Resp %d\n", __FUNCTION__, p_data->inq_cmpl.num_resps);
LOG_ERROR("connect the device "BT_BD_ADDR_STR", client_if=%d\n",
BT_BD_ADDR_HEX(obj_addr), client_if);
/* scan complete, start connect*/
BTA_GATTC_Open(client_if, obj_addr, true, transport);
}
break;
default:
LOG_ERROR("%s : unknown event 0x%x", __FUNCTION__, event);
}
}
/************************************************************************************
* * Function bta_scan_param_setup_cback
* *
* * Description set scan param callback.it will be called after setting scan parameter
* *
* * Return NULL
**************************************************************************************/
static void bta_scan_param_setup_cback(tGATT_IF c_client_if, tBTM_STATUS status)
{
client_if = c_client_if;
LOG_ERROR("\nset scan params complete: status=%d, client_if=%d\n", status, client_if);
/*start scan*/
BTA_DmBleObserve(true, 8, bta_scan_result_callback);
}
/************************************************************************************
* * Function bta_gattc_callback
* *
* * Description app register callback
* *
* * Return NULL
**************************************************************************************/
static void bta_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data)
{
switch (event)
{
case BTA_GATTC_REG_EVT:
{
tBTA_GATT_STATUS status = p_data->reg_oper.status;
client_if = p_data->reg_oper.client_if;
LOG_ERROR("%s:register complete: event=%d, status=%d, client_if=%d\n", __FUNCTION__, event, status, client_if);
UINT8 scan_interval = 0x50;
UINT8 scan_window = 0x30;
tBLE_SCAN_MODE scan_mode = BTM_BLE_SCAN_MODE_ACTI;
bac_register();
/*register complete,set scan parameter*/
BTA_DmSetBleScanParams(client_if, scan_interval, scan_window, scan_mode,
bta_scan_param_setup_cback);
}
break;
/*connect callback*/
case BTA_GATTC_OPEN_EVT:
{
LOG_ERROR("\n%s:device is connected "BT_BD_ADDR_STR", client_if=%d, status=%d, connect_id=%d\n",
__FUNCTION__, BT_BD_ADDR_HEX(p_data->open.remote_bda), p_data->open.client_if,
p_data->open.status, p_data->open.conn_id);
/*return whether the remote device is currently connected*/
int is_connected = BTA_DmGetConnectionState(p_data->open.remote_bda);
LOG_ERROR("is_connected=%d\n",is_connected);
/*get the energy info of the controller*/
/*read battery level*/
int conn_id = p_data->open.conn_id;
/*discover service*/
// BTA_GATTC_ServiceSearchRequest(conn_id, NULL);
}
break;
/*
case BTA_GATTC_SEARCH_RES_EVT:
{
// tBTA_GATTC_SRVC_RES service_result;
LOG_ERROR("find the service,uuid=0x%x, is_primary=%d\n",
get_uuid16(&p_data->srvc_res.service_uuid.id.uuid),
p_data->srvc_res.service_uuid.is_primary);
}
break;
case BTA_GATTC_SEARCH_CMPL_EVT:
{
LOG_ERROR("search service complete, conn_id=%d,status=%d\n", p_data->search_cmpl.conn_id,
p_data->search_cmpl.status);
//get first characteristic of battey service
LOG_ERROR("get first characteristic of battery service\n");
tBTA_GATT_STATUS status;
tBTA_GATT_SRVC_ID battery_srvc_id;
tBTA_GATTC_CHAR_ID out_char_id;
tGATT_CHAR_PROP out_char_prop;
bta_le_fill_16bits_srvc_id(TRUE, 0, UUID_SERVCLASS_BATTERY, &battery_srvc_id);
status = BTA_GATTC_GetFirstChar(p_data->search_cmpl.conn_id, &battery_srvc_id, NULL,
&out_char_id, &out_char_prop);
if(status == 0)
{
LOG_ERROR("the first char:srvc_id=0x%x,char_id=0x%x, property = %d\n",
get_uuid16(&out_char_id.srvc_id.id.uuid), get_uuid16(&out_char_id.char_id.uuid),
out_char_prop);
//read battery level
tBTA_GATTC_CHAR_ID battery_char_id;
bta_le_fill_16bits_srvc_id(TRUE, 0, UUID_SERVCLASS_BATTERY, &battery_char_id.srvc_id);
bta_le_fill_16bits_char_id(0, GATT_UUID_BATTERY_LEVEL, &battery_char_id.char_id);
BTA_GATTC_ReadCharacteristic(p_data->search_cmpl.conn_id, &battery_char_id,
BTA_GATT_AUTH_REQ_NONE);
}
}
break;
case BTA_GATTC_READ_CHAR_EVT:
{
LOG_ERROR("\nread characteristic:connect_id=%d, status=%d\n",
p_data->read.conn_id, p_data->read.status);
LOG_ERROR("srvc_id=0x%x,char_id=0x%x,descr_type=0x%x\n",
get_uuid16(&p_data->read.srvc_id.id.uuid),
get_uuid16(&p_data->read.char_id.uuid),
get_uuid16(&p_data->read.descr_type.uuid));
if(get_uuid16(&p_data->read.descr_type.uuid) != GATT_UUID_CHAR_AGG_FORMAT
&& p_data->read.p_value->unformat.len > 0
&& p_data->read.p_value->unformat.p_value != NULL)
{
LOG_ERROR("read the value: len=%d, value=%d\n", p_data->read.p_value->unformat.len,
*(p_data->read.p_value->unformat.p_value));
}
}
break;
*/
default:
LOG_ERROR("%s:unknown event: %d\n", __FUNCTION__, event);
}
}
/************************************************************************************
* * Function ble_client_appRegister
* *
* * Description app register function
* *
* * Return NULL
**************************************************************************************/
void ble_client_appRegister(void)
{
bt_uuid_t uuid;
tBT_UUID t_uuid;
memcpy(&uuid, BASE_UUID, sizeof(bt_uuid_t));
btif_to_bta_uuid(&t_uuid, &uuid);
LOG_ERROR("register application\n");
BTA_GATTC_AppRegister(&t_uuid, bta_gattc_callback);
/*battery service register*/
// bac_register();
}
void gattc_client_test(void)
{
BTM_SetTraceLevel(BT_TRACE_LEVEL_DEBUG);
ble_client_appRegister();
}

Wyświetl plik

@ -0,0 +1,291 @@
/***************************************************************
*
* This file is for gatt server device. It instantiates BATTERY
* sevice. It can be scanned and connected by central device,
* and the client will get the BAS value. It calls the API bta
* layer provides.
*
****************************************************************/
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
#include <stdio.h>
#include "bta_api.h"
#include "bta_gatt_api.h"
#include "controller.h"
#include "gatt_int.h"
#include "bt_trace.h"
#include "btm_api.h"
#include "bt_types.h"
#include "dis_api.h"
#include "bt_app_common.h"
//#include "app_button.h"
#include "button_pro.h"
#include "hid_le_prf.h"
#include "prf_defs.h"
#include "hcimsgs.h"
#include "bt_app_defs.h"
#define BT_BD_ADDR_STR "%02x:%02x:%02x:%02x:%02x:%02x"
#define BT_BD_ADDR_HEX(addr) addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]
tBTA_GATTS_IF server_if;
static unsigned char DIS_UUID[16] = {
0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
0x00, 0x10, 0x00, 0x00, 0x0a, 0x18, 0x00, 0x00
};
static unsigned char BASE_UUID[16] = {
0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
UINT16 ijiazu_uuid = 0xffff;
tBTA_BLE_SERVICE ijiazu_service = {
0x01, //only one service in the ijiazu button profile
false,
&ijiazu_uuid
}; /* 16 bits services */
UINT8 beacon_manu[25] = {0x4c, 0x00,0x02, 0x15, 0xfd, 0xa5, 0x06, 0x93, 0xa4, 0xe2,
0x4f, 0xb1, 0xaf, 0xcf, 0xc6, 0xeb, 0x07, 0x64, 0x78, 0x25,
0x27, 0x32, 0xe6, 0x08, 0xc5};
//UINT8 ijiazu_manu[17] = {0xff,0x20,0x14,0x07,0x22,0x00,0x02,0x5B,0x00,0x33,0x49,0x31,0x30,0x4a,0x30,0x30,0x31};
UINT8 ijiazu_manu[17] = {0xff,0x20,0x14,0x07,0x22,0x00,0x02,0x5B,0x00,0x33,0x49,0x31,0x30,0x4a,0x30,0x30,0x31};
tBTA_BLE_MANU p_ijiazu_manu = {sizeof(ijiazu_manu),ijiazu_manu}; /* manufacturer data */
BD_ADDR rand_ijiazu_addr = {0x00,0x02,0x5B,0x00,0x32,0x55};
tESP_BLE_ADV_DATA ijiazu_adv_data[ADV_SCAN_IDX_MAX] =
{
[BLE_ADV_DATA_IDX] = {
.adv_name = "Espressif_008",
{
{0,0},
NULL, //no manufature data to be setting in the ijiazu adervetisiing datas
&ijiazu_service,
NULL, //the 128 bits service uuid set to null(not used)
NULL, //the 32 bits Service UUID set to null(not used)
NULL, //16 bits services Solicitation UUIDs set to null(not used)
NULL, //List of 32 bit Service Solicitation UUIDs set to null(not used)
NULL, //List of 128 bit Service Solicitation UUIDs set to null(not used)
NULL, //proprietary data set to null(not used)
NULL, //service data set not null(no service data to be sent)
0x0200, //device type : generic display
BTA_DM_GENERAL_DISC, // General discoverable.
0xFE //the tx power value,defult value is 0
},
},
[BLE_SCAN_RSP_DATA_IDX] = {
.adv_name = NULL,
{
{0,0},
&p_ijiazu_manu,
NULL,
NULL, //the 128 bits service uuid set to null(not used)
NULL, //the 32 bits Service UUID set to null(not used)
NULL, //16 bits services Solicitation UUIDs set to null(not used)
NULL, //List of 32 bit Service Solicitation UUIDs set to null(not used)
NULL, //List of 128 bit Service Solicitation UUIDs set to null(not used)
NULL, //proprietary data set to null(not used)
NULL, //service data set not null(no service data to be sent)
0x0000, //device type : generic display
0x00, // General discoverable.
0x00}, //the tx power value,defult value is 0
}
};
static void SimpleDataCallBack(UINT8 app_id, UINT8 event, UINT8 len, UINT8 *p_data);
typedef struct {
uint8_t uu[16];
} bt_uuid_t;
int uuidType(unsigned char* p_uuid)
{
int i = 0;
int match = 0;
int all_zero = 1;
for(i = 0; i != 16; ++i)
{
if (i == 12 || i == 13)
continue;
if (p_uuid[i] == BASE_UUID[i])
++match;
if (p_uuid[i] != 0)
all_zero = 0;
}
if (all_zero)
return 0;
if (match == 12)
return LEN_UUID_32;
if (match == 14)
return LEN_UUID_16;
return LEN_UUID_128;
}
/*16-bits uuid to the structure of holding any type of UUID*/
void btif_to_bta_uuid(tBT_UUID *p_dest, bt_uuid_t *p_src)
{
char *p_byte = (char*)p_src;
int i = 0;
p_dest->len = uuidType(p_src->uu);
switch (p_dest->len)
{
case LEN_UUID_16:
p_dest->uu.uuid16 = (p_src->uu[13] << 8) + p_src->uu[12];
break;
case LEN_UUID_32:
p_dest->uu.uuid32 = (p_src->uu[13] << 8) + p_src->uu[12];
p_dest->uu.uuid32 += (p_src->uu[15] << 24) + (p_src->uu[14] << 16);
break;
case LEN_UUID_128:
for(i = 0; i != 16; ++i)
p_dest->uu.uuid128[i] = p_byte[i];
break;
default:
LOG_ERROR("%s: Unknown UUID length %d!", __FUNCTION__, p_dest->len);
break;
}
}
/*set advertising config callback*/
static void bta_gatts_set_adv_data_cback(tBTA_STATUS call_status)
{
LOG_ERROR("set advertising config:status=%d\n", call_status);
/*dis init*/
/* tDIS_ATTR_MASK dis_attr_mask;
dis_attr_mask = DIS_ATTR_SYS_ID_BIT | DIS_ATTR_MODEL_NUM_BIT | DIS_ATTR_SERIAL_NUM_BIT |
DIS_ATTR_FW_NUM_BIT | DIS_ATTR_HW_NUM_BIT | DIS_ATTR_SW_NUM_BIT | DIS_ATTR_MANU_NAME_BIT |
DIS_ATTR_IEEE_DATA_BIT | DIS_ATTR_PNP_ID_BIT;
DIS_SrInit(dis_attr_mask);
*/
/*instantiate a battery service*/
//bas_register();
/*instantiate the driver for button profile*/
//app_button_init();
/*instantiate a button service*/
button_init(SimpleDataCallBack);
/*instantiate a hid device service*/
//hidd_le_init();
/*start advetising*/
// BTA_GATTS_Listen(server_if, true, NULL);
}
/*register callback*/
void bta_gatts_callback(tBTA_GATTS_EVT event, tBTA_GATTS* p_data)
{
switch (event)
{
case BTA_GATTS_REG_EVT:
{
tBTA_GATT_STATUS status = p_data->reg_oper.status;
server_if = p_data->reg_oper.server_if;
LOG_ERROR("register complete: event=%d, status=%d, server_if=%d\n",
event, status, server_if);
LOG_ERROR("set advertising parameters\n");
//set the advertising data to the btm layer
ESP_AppBleConfigadvData(&ijiazu_adv_data[BLE_ADV_DATA_IDX],
bta_gatts_set_adv_data_cback);
//set the adversting data to the btm layer
ESP_AppBleSetScanRsp(&ijiazu_adv_data[BLE_SCAN_RSP_DATA_IDX],NULL);
}
break;
/*connect callback*/
case BTA_GATTS_CONNECT_EVT:
{
LOG_ERROR("\ndevice is connected "BT_BD_ADDR_STR", server_if=%d,reason=0x%x,connect_id=%d\n",
BT_BD_ADDR_HEX(p_data->conn.remote_bda), p_data->conn.server_if,
p_data->conn.reason, p_data->conn.conn_id);
/*return whether the remote device is currently connected*/
int is_connected = BTA_DmGetConnectionState(p_data->conn.remote_bda);
LOG_ERROR("is_connected=%d\n",is_connected);
}
break;
default:
LOG_ERROR("unsettled event: %d\n", event);
}
}
#define HEADER_SSID "ssid"
#define HEADER_PASSWD "passwd"
#define HEADER_CONFIRM "confirm"
extern void wifi_set_blue_config(char *ssid, char *passwd);
static char tmp_ssid[33];
static char tmp_passwd[33];
static void SimpleDataCallBack(UINT8 app_id, UINT8 event, UINT8 len, UINT8 *p_data)
{
char *p = NULL;
LOG_ERROR("the data is:%s\n", p_data);
#if 0
switch(event)
{
case RECEIVE_NET_PASSWD_EVT:
LOG_ERROR("Received the network passwork");
break;
case RECEIVE_NET_SSD_EVT:
LOG_ERROR("Received the network SSID");
break;
default:
break;
}
#endif
p = strstr(p_data, HEADER_SSID);
if (p) {
ets_printf("SSID: %s\n", p+strlen(HEADER_SSID)+1);
strcpy(tmp_ssid, p+strlen(HEADER_SSID)+1);
}
p = strstr(p_data, HEADER_PASSWD);
if (p) {
ets_printf("PASSWORD: %s\n", p+strlen(HEADER_PASSWD)+1);
strcpy(tmp_passwd, p+strlen(HEADER_PASSWD)+1);
}
p = strstr(p_data, HEADER_CONFIRM);
if (p) {
ets_printf("CONFIRM\n");
wifi_set_blue_config(tmp_ssid, tmp_passwd);
}
}
static void ble_server_appRegister(void)
{
bt_uuid_t uuid;
tBT_UUID t_uuid;
memcpy(&uuid, BASE_UUID, sizeof(bt_uuid_t));
//memcpy(&uuid, DIS_UUID, sizeof(bt_uuid_t));
btif_to_bta_uuid(&t_uuid, &uuid);
LOG_ERROR("register gatts application\n");
BTA_GATTS_AppRegister(&t_uuid, bta_gatts_callback);
}
void gatts_server_test(void)
{
BTM_SetTraceLevel(BT_TRACE_LEVEL_DEBUG);
ble_server_appRegister();
}

Wyświetl plik

@ -0,0 +1,21 @@
#
# Main Makefile. This is basically the same as a component makefile.
#
# This Makefile should, at the very least, just include $(SDK_PATH)/make/component_common.mk. By default,
# this will take the sources in the src/ directory, compile them and link them into
# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable,
# please read the ESP-IDF documents if you need to do this.
#
COMPONENT_SRCDIRS := \
app_core \
app_client_profiles/battery_c \
app_client_profiles \
app_profiles/app_sample_button \
app_profiles \
app_project
CFLAGS += -Wno-error=unused-label -Wno-error=return-type -Wno-error=missing-braces -Wno-error=pointer-sign -Wno-error=parentheses -I./include
include $(IDF_PATH)/make/component_common.mk

Wyświetl plik

@ -0,0 +1,62 @@
/**
****************************************************************************************
*
* @file app_button.h
*
* @brief button Service Application entry point
*
* Copyright (C) ESPRESSIF 2016
* Created by Yulong at 2016/02/24
*
*
****************************************************************************************
*/
/*
* DEFINES
****************************************************************************************
*/
#define BUTTON_HEAD (0x01)
#define BUTTON_PRESS_EVT (0x10)
//the key value enum
enum
{
Button_Up = 0x01,
Button_Voice = 0x02,
Button_OK = 0x04,
Button_Down = 0x08,
Button_Back = 0x10,
};
typedef struct {
uint8_t key_val; //button val
uint8_t head; //the head of the frame
}key_frame;
typedef struct
{
bool button_press;
key_frame key_msg;
}app_key_env;
extern app_key_env key_press;
/*
* FUNCTIONS DECLARATION
****************************************************************************************
*/
void app_button_init(void);
void GPIO_isr_callback(void* arg);
uint8_t check_sum(uint8_t *check_array,uint8_t len);

Wyświetl plik

@ -0,0 +1,47 @@
#ifndef __BT_APP_COMMON_H__
#define __BT_APP_COMMON_H__
#include <stdint.h>
#include "osi.h"
#include "bt_common_types.h"
/** Bluetooth Error Status */
/** originally defined in bluetooth.h */
typedef enum {
BT_STATUS_SUCCESS,
BT_STATUS_FAIL,
BT_STATUS_NOT_READY,
BT_STATUS_NOMEM,
BT_STATUS_BUSY,
BT_STATUS_DONE,
BT_STATUS_UNSUPPORTED,
BT_STATUS_PARAM_INVALID,
BT_STATUS_UNHANDLED,
BT_STATUS_AUTH_FAILURE,
BT_STATUS_RMT_DEV_DOWN
} bt_status_t;
/* BT APP Events */
#define BT_EVT_APP (0xB000)
#define BT_EVT_APP_CONTEXT_SWITCH (0x0001 | BT_EVT_APP)
typedef void (tBTAPP_CBACK) (uint16_t event, char *p_param);
typedef void (tBTAPP_COPY_CBACK) (uint16_t event, char *p_dest, char *p_src);
typedef struct
{
BT_HDR hdr;
tBTAPP_CBACK* p_cb; /* context switch callback */
/* parameters passed to callback */
UINT16 event; /* message event id */
char p_param[0]; /* parameter area needs to be last */
} tBTAPP_CONTEXT_SWITCH_CBACK;
bt_status_t bt_app_transfer_context (tBTAPP_CBACK *p_cback, UINT16 event, char* p_params, int param_len, tBTAPP_COPY_CBACK *p_copy_cback);
void bt_app_init_ok(UNUSED_ATTR uint16_t event, UNUSED_ATTR char *p_param);
void bt_app_task_start_up(void);
#endif /* __BT_APP_COMMON_H__ */

Wyświetl plik

@ -0,0 +1,23 @@
#include "bta_api.h"
#include "btm_ble_api.h"
enum
{
BLE_ADV_DATA_IDX,
BLE_SCAN_RSP_DATA_IDX,
ADV_SCAN_IDX_MAX
};
typedef struct
{
char *adv_name; //set the device name to be sent on the advertising
tBTA_BLE_ADV_DATA ble_adv_data;
}tESP_BLE_ADV_DATA;
extern void ESP_AppBleConfigadvData(tESP_BLE_ADV_DATA *adv_data,
tBTA_SET_ADV_DATA_CMPL_CBACK *p_adv_data_cback);
extern void ESP_AppBleSetScanRsp(tESP_BLE_ADV_DATA *scan_rsp_data,
tBTA_SET_ADV_DATA_CMPL_CBACK *p_scan_rsp_data_cback);

Wyświetl plik

@ -0,0 +1,46 @@
/******************************************************************************
*
* Copyright (C) 1999-2013 Broadcom Corporation
*
* 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.
*
******************************************************************************/
/*******************************************************************************
**
** Header file for gatt client.
**
********************************************************************************/
#include "bt_target.h"
#include "gatt_api.h"
#include "gattdefs.h"
/*******************************************************************************
** BATTERY CLIENT API
*******************************************************************************/
/***************************************************************
**
** Function bac_register
**
** Description register app for battery service
**
****************************************************************/
extern void bac_register(void);
extern void gattc_client_test(void);
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -0,0 +1,10 @@
#
# Main Makefile. This is basically the same as a component makefile.
#
# This Makefile should, at the very least, just include $(SDK_PATH)/make/component_common.mk. By default,
# this will take the sources in the src/ directory, compile them and link them into
# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable,
# please read the ESP-IDF documents if you need to do this.
#
include $(IDF_PATH)/make/component_common.mk

Wyświetl plik

@ -0,0 +1,127 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event_loop.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "bt.h"
#include "bta_api.h"
extern tBTA_STATUS BTA_DisableBluetooth(void);
extern void phy_set_wifi_mode_only(bool wifi_only);
extern void bte_main_boot_entry(void *);
extern void bt_app_task_start_up(void);
extern void bt_app_task_shut_down(void);
extern void bt_app_core_start(void);
#define WIFI_LIST_NUM 10
/* FreeRTOS event group to signal when we are connected & ready to make a request */
static EventGroupHandle_t wifi_event_group;
/* The event group allows multiple bits for each event,
but we only care about one event - are we connected
to the AP with an IP? */
const int CONNECTED_BIT = BIT0;
static wifi_scan_config_t scan_config;
static wifi_config_t sta_config;
static char tmp_ssid[33];
static char tmp_passwd[33];
static bool confirm = false;
void wifi_set_blue_config(char *ssid, char *passwd)
{
memset(tmp_ssid, 0, 33);
memset(tmp_passwd, 0, 33);
strcpy(tmp_ssid, ssid);
strcpy(tmp_passwd, passwd);
confirm = true;
printf("confirm true\n");
}
static esp_err_t event_handler(void *ctx, system_event_t *event)
{
switch(event->event_id) {
case SYSTEM_EVENT_STA_START:
esp_wifi_connect();
break;
case SYSTEM_EVENT_STA_GOT_IP:
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
/* This is a workaround as ESP32 WiFi libs don't currently
auto-reassociate. */
esp_wifi_connect();
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
break;
default:
break;
}
return ESP_OK;
}
static void initialise_wifi(void)
{
tcpip_adapter_init();
wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) );
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
ESP_ERROR_CHECK( esp_wifi_start() );
}
static int loop = 0;
void wifiTestTask(void *pvParameters)
{
esp_err_t ret;
while (1) {
vTaskDelay(1000 / portTICK_PERIOD_MS);
if (confirm) {
confirm = false;
BTA_DisableBluetooth();
strcpy(sta_config.sta.ssid, tmp_ssid);
strcpy(sta_config.sta.password, tmp_passwd);
sta_config.sta.bssid_set = 0;
ret = esp_wifi_disconnect();
printf("esp_wifi config\n");
esp_wifi_set_config(WIFI_IF_STA, &sta_config);
printf("esp_wifi connect\n");
ret = esp_wifi_connect();
if (ret != ESP_OK) {
printf("esp_wifi connect failed\n");
}
}
}
}
void app_main()
{
esp_err_t ret;
phy_set_wifi_mode_only(0);
nvs_flash_init();
system_init();
initialise_wifi();
vTaskDelay(3000 / portTICK_PERIOD_MS);
bt_controller_init();
xTaskCreatePinnedToCore(&wifiTestTask, "wifiTestTask", 2048, NULL, 20, NULL, 0);
bt_app_task_start_up();
bte_main_boot_entry(bt_app_core_start);
}