蓝牙网关(备份)

本代码集成了蓝牙,wifi, mqtt。重点是判断蓝牙的广播包和响应包数据,最后根据响应包的最后一个字节来决定怎样发送mqtt。 本代码采用蓝牙bluedroid。最好用idf 5.3.4 和esp32。我用idf v5.5和esp32s3 没有通过。

广播包:0x0201060709'D''O''O''R''_''1'

响应包:0x09FFFFFF'D''O''O''R''_''1' 根据响应包最后一位1或者0来发送mqtt命令

复制代码
#include "stdint.h"

#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <inttypes.h>

#include "esp_bt.h"
#include "nvs_flash.h"
#include "esp_log.h"
#include "esp_bt_defs.h"
#include "esp_bt_main.h"
#include "esp_gatt_defs.h"
#include "esp_gattc_api.h"
#include "esp_gap_ble_api.h"
#include "freertos/FreeRTOS.h"


#include "esp_event.h"
#include "esp_netif.h"
#include "esp_wifi.h"
#include "mqtt_client.h"

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

static const char* DEMO_TAG = "bleserver";
static const char *TAG = "BLE_MQTT";

// ===== WiFi 配置 =====
#define WIFI_SSID     "CMCC-6ZN9" //"ChinaNet-AETP5V"// 
#define WIFI_PASS     "2KJKWEML"  //"wf123456" //

// ===== MQTT 配置 =====
#define MQTT_BROKER_URI "mqtt://192.168.101.233:1883"

static esp_mqtt_client_handle_t mqtt_client;

// ===== MQTT 初始化 =====
static void mqtt_app_start(void)
{
    esp_mqtt_client_config_t mqtt_cfg = {
        .broker.address.uri = MQTT_BROKER_URI,
    };
    mqtt_client = esp_mqtt_client_init(&mqtt_cfg);
    esp_mqtt_client_start(mqtt_client);
}


//--------------------------------------------------------------------------

//static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t* param);


static esp_ble_scan_params_t ble_scan_params = {
    .scan_type              = BLE_SCAN_TYPE_ACTIVE,       // 扫描类型:主动扫描(可收到扫描响应)或被动扫描
    .own_addr_type          = BLE_ADDR_TYPE_PUBLIC,       // 本机地址类型:公共地址
    .scan_filter_policy     = BLE_SCAN_FILTER_ALLOW_ALL,  // 扫描过滤策略:允许所有广播包
    .scan_interval          = 0x50,                       // 扫描间隔单位:0.625ms,0x50 = 50*0.625ms = 31.25ms
    .scan_window            = 0x30,                       // 扫描窗口单位:0.625ms,0x30 = 48*0.625ms = 30ms
    .scan_duplicate         = BLE_SCAN_DUPLICATE_DISABLE  // 是否过滤重复广播包
};



static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t* param)
{
    esp_err_t err;

    switch(event)
    {
        case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT: //确认扫描参数已生效。可以在这个事件中启动扫描。
       {
            
            uint32_t duration = 0;
            esp_ble_gap_start_scanning(duration);
            break;
        }
        case ESP_GAP_BLE_SCAN_START_COMPLETE_EVT:    //扫描启动完成
      {  
            if((err = param->scan_start_cmpl.status) != ESP_BT_STATUS_SUCCESS) {
                ESP_LOGE(DEMO_TAG,"Scan start failed: %s", esp_err_to_name(err));
            }
            else {
                ESP_LOGI(DEMO_TAG,"Start scanning...");
            }
            break;
        }
        case ESP_GAP_BLE_SCAN_RESULT_EVT:  // 收到广播包,响应包
       {
          
       // 广播包
    int n= param->scan_rst.adv_data_len;
 //   printf("Adv data (%d bytes): ",n);

    char adv[n];
    memset(adv,'\0',n); 
    int bz=0;  

    static char adv1[10][31]={0};
    int k=-1;
    int m=0;
    for (int i = 0; i <n; i++) {
       adv[i]=param->scan_rst.ble_adv[i];
       if(bz==0) {
             k++;
             m=0;
		bz=adv[i];
             continue;
	}
       adv1[k][m]=adv[i];
       bz=bz-1;
       m++;
    }
    
    if(adv1[1][0]==0x9){
        for(int t=1;t<7;t++){
     		printf("%x",adv1[1][t]);
        }
        printf("\n");

      //响应包
      //  printf("%x\n",param->scan_rst.ble_adv[n+0])
	int sn=param->scan_rst.ble_adv[n+0];   //广播包后面是响应包,第一个字节为响应包长度 我的响应包:0x09 FF FFFF "DOOR_1" 判断标志为最后             //一个字节
/*	for(int k=0;k<(sn+1);k++){
            printf("%x",param->scan_rst.ble_adv[n+k]);
       }  
*/ 
 //      printf("%x\n",param->scan_rst.ble_adv[n+sn]);

	

        // 控制灯
        if ( param->scan_rst.ble_adv[n+sn]==0x31){
        	    esp_mqtt_client_publish(mqtt_client, "light/control", "on", 0, 1, 0);
        	    printf("%s\n","on");
		
	 }
        if ( param->scan_rst.ble_adv[n+sn]==0x30){
        	    esp_mqtt_client_publish(mqtt_client, "light/control", "off", 0, 1, 0);
        	    printf("%s\n","off");
		
	}
          
    }
  
            break;
        }

        case ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT:{
     
        }
        default:
            break;
    }
}

// ===== WiFi 初始化 =====
static void wifi_event_handler(void* arg, esp_event_base_t event_base,
                               int32_t event_id, void* event_data)
{
    if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
        esp_wifi_connect();
    } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
        ESP_LOGI(TAG, "Disconnected. Reconnecting...");
        esp_wifi_connect();
    } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
        ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
        ESP_LOGI(TAG, "Got IP:" IPSTR, IP2STR(&event->ip_info.ip));
         mqtt_app_start();
         
 	  esp_bluedroid_init();
        esp_bluedroid_enable();    
	 esp_ble_gap_register_callback(esp_gap_cb);
       esp_ble_gap_set_scan_params(&ble_scan_params); 

    }
}

static void wifi_init(void)
{
    ESP_LOGI(TAG, "Init WiFi");
    esp_netif_init();
    esp_event_loop_create_default();
    esp_netif_create_default_wifi_sta();

    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));

    esp_event_handler_instance_t instance_any_id;
    esp_event_handler_instance_t instance_got_ip;
    ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
                                                        ESP_EVENT_ANY_ID,
                                                        &wifi_event_handler,
                                                        NULL,
                                                        &instance_any_id));
    ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
                                                        IP_EVENT_STA_GOT_IP,
                                                        &wifi_event_handler,
                                                        NULL,
                                                        &instance_got_ip));

    wifi_config_t wifi_config = {
        .sta = {
            .ssid = WIFI_SSID,
            .password = WIFI_PASS,
        },
    };
    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
    ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
    ESP_ERROR_CHECK(esp_wifi_start());
}



void app_main(void)
{

    esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
    ESP_ERROR_CHECK(nvs_flash_erase());
    ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
    
    ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT));
    esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
    esp_bt_controller_init(&bt_cfg);
    esp_bt_controller_enable(ESP_BT_MODE_BLE);

  //   esp_bluedroid_init();
 //   esp_bluedroid_enable();
   
  // esp_ble_gap_register_callback(esp_gap_cb);


    /*<! set scan parameters */
 //   esp_ble_gap_set_scan_params(&ble_scan_params);

    wifi_init();
}
相关推荐
上海云盾安全满满1 小时前
高防 IP 是如何帮助数藏行业防刷
网络·网络协议·tcp/ip
mit6.8244 小时前
bfs|栈
算法
xu_yule5 小时前
Linux_12(进程信号)内核态和用户态+处理信号+不可重入函数+volatile
linux·运维·服务器
虾..5 小时前
Linux 环境变量&&进程优先级
linux·运维·服务器
i***t9195 小时前
Linux下MySQL的简单使用
linux·mysql·adb
偶像你挑的噻5 小时前
11-Linux驱动开发-I2C子系统–mpu6050简单数据透传驱动
linux·驱动开发·stm32·嵌入式硬件
CoderYanger6 小时前
优选算法-栈:67.基本计算器Ⅱ
java·开发语言·算法·leetcode·职场和发展·1024程序员节
jllllyuz6 小时前
Matlab实现基于Matrix Pencil算法实现声源信号角度和时间估计
开发语言·算法·matlab
稚辉君.MCA_P8_Java6 小时前
DeepSeek 插入排序
linux·后端·算法·架构·排序算法
多多*6 小时前
Java复习 操作系统原理 计算机网络相关 2025年11月23日
java·开发语言·网络·算法·spring·microsoft·maven