#include "Wireless.h" uint16_t BLE_NUM = 0; uint16_t WIFI_NUM = 0; bool Scan_finish = 0; bool WiFi_Scan_Finish = 0; bool BLE_Scan_Finish = 0; wifi_ap_info_t *wifi_ap_list = NULL; uint16_t wifi_ap_count = 0; ble_device_info_t *ble_device_list = NULL; esp_err_t Wireless_Init(void) { // Initialize NVS. esp_err_t ret = nvs_flash_init(); // 初始化Flash if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { // 如果Flash有错误,则进行修复 ESP_ERROR_CHECK(nvs_flash_erase()); // 清空Flash ret = nvs_flash_init(); // 重新初始化Flash } ESP_ERROR_CHECK( ret ); // 检查错误 // WiFi 手动调用Wifi初始化 // xTaskCreatePinnedToCore( // WIFI_Init, // "WIFI task", // 4096, // NULL, // 1, // NULL, // 0); // BLE 当前工程不启用蓝牙 // xTaskCreatePinnedToCore( // BLE_Init, // "BLE task", // 4096, // NULL, // 2, // NULL, // 0); return ret; } esp_err_t WIFI_Init(void *arg) { esp_netif_init(); // 初始化网络接口 esp_event_loop_create_default(); // 创建事件循环 esp_netif_create_default_wifi_sta(); // 创建默认的WiFi Station wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); // 创建WiFi初始化配置(使用默认配置) esp_wifi_init(&cfg); // 初始化WiFi esp_wifi_set_mode(WIFI_MODE_STA); // 设置WiFi模式为Station esp_err_t ret = esp_wifi_start(); // 启动WiFi return ret; } uint16_t WIFI_Scan(void) { uint16_t ap_count = 0; esp_wifi_scan_start(NULL, true); // 开始扫描 ESP_ERROR_CHECK(esp_wifi_scan_get_ap_num(&ap_count)); // 分配内存保存AP信息 if (wifi_ap_list) { // 如果已有内存,则释放 free(wifi_ap_list); } wifi_ap_list = malloc(ap_count * sizeof(wifi_ap_info_t)); if (!wifi_ap_list) { printf("Failed to allocate memory for WiFi AP list\n"); return 0; } // 获取AP列表 wifi_ap_record_t *ap_records = malloc(ap_count * sizeof(wifi_ap_record_t)); if (!ap_records) { printf("Failed to allocate memory for AP records\n"); free(wifi_ap_list); // 释放AP列表内存 return 0; } ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&ap_count, ap_records)); // 保存AP信息 wifi_ap_count = ap_count; for (int i = 0; i < ap_count; i++) { memset(wifi_ap_list[i].ssid, 0, sizeof(wifi_ap_list[i].ssid)); strncpy(wifi_ap_list[i].ssid, (char*)ap_records[i].ssid, sizeof(wifi_ap_list[i].ssid) - 1); memcpy(wifi_ap_list[i].bssid, ap_records[i].bssid, 6); wifi_ap_list[i].rssi = ap_records[i].rssi; wifi_ap_list[i].authmode = ap_records[i].authmode; } free(ap_records); esp_wifi_scan_stop(); WiFi_Scan_Finish = 1; if (BLE_Scan_Finish == 1 || WiFi_Scan_Finish == 1) { Scan_finish = 1; } return ap_count; } #define GATTC_TAG "GATTC_TAG" #define SCAN_DURATION 5 #define MAX_DISCOVERED_DEVICES 100 typedef struct { uint8_t address[6]; bool is_valid; } discovered_device_t; static discovered_device_t discovered_devices[MAX_DISCOVERED_DEVICES]; static size_t num_discovered_devices = 0; static size_t num_devices_with_name = 0; static bool is_device_discovered(const uint8_t *addr) { for (size_t i = 0; i < num_discovered_devices; i++) { if (memcmp(discovered_devices[i].address, addr, 6) == 0) { return true; } } return false; } static void add_device_to_list(const uint8_t *addr) { if (num_discovered_devices < MAX_DISCOVERED_DEVICES) { memcpy(discovered_devices[num_discovered_devices].address, addr, 6); discovered_devices[num_discovered_devices].is_valid = true; num_discovered_devices++; } } static bool extract_device_name(const uint8_t *adv_data, uint8_t adv_data_len, char *device_name, size_t max_name_len) { size_t offset = 0; while (offset < adv_data_len) { if (adv_data[offset] == 0) break; uint8_t length = adv_data[offset]; if (length == 0 || offset + length > adv_data_len) break; uint8_t type = adv_data[offset + 1]; if (type == ESP_BLE_AD_TYPE_NAME_CMPL || type == ESP_BLE_AD_TYPE_NAME_SHORT) { if (length > 1 && length - 1 < max_name_len) { memcpy(device_name, &adv_data[offset + 2], length - 1); device_name[length - 1] = '\0'; return true; } else { return false; } } offset += length + 1; } return false; } static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) { static char device_name[100]; switch (event) { case ESP_GAP_BLE_SCAN_RESULT_EVT: if (param->scan_rst.search_evt == ESP_GAP_SEARCH_INQ_RES_EVT) { if (!is_device_discovered(param->scan_rst.bda)) { add_device_to_list(param->scan_rst.bda); BLE_NUM++; // 分配内存保存BLE设备信息 if (!ble_device_list) { ble_device_list = malloc(MAX_DISCOVERED_DEVICES * sizeof(ble_device_info_t)); if (!ble_device_list) { printf("Failed to allocate memory for BLE device list\n"); return; } } // 保存设备信息 int idx = BLE_NUM - 1; if (idx < MAX_DISCOVERED_DEVICES) { memset(ble_device_list[idx].name, 0, sizeof(ble_device_list[idx].name)); if (extract_device_name(param->scan_rst.ble_adv, param->scan_rst.adv_data_len, device_name, sizeof(device_name))) { strncpy(ble_device_list[idx].name, device_name, sizeof(ble_device_list[idx].name) - 1); num_devices_with_name++; } else { strncpy(ble_device_list[idx].name, "Unknown", sizeof(ble_device_list[idx].name) - 1); } memcpy(ble_device_list[idx].address, param->scan_rst.bda, 6); ble_device_list[idx].rssi = param->scan_rst.rssi; } } } break; case ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT: ESP_LOGI(GATTC_TAG, "Scan complete. Total devices found: %d (with names: %d)", BLE_NUM, num_devices_with_name); break; default: break; } } void BLE_Init(void *arg) { 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_err_t ret = esp_bt_controller_init(&bt_cfg); if (ret) { printf("%s initialize controller failed: %s\n", __func__, esp_err_to_name(ret)); return;} ret = esp_bt_controller_enable(ESP_BT_MODE_BLE); if (ret) { printf("%s enable controller failed: %s\n", __func__, esp_err_to_name(ret)); return;} ret = esp_bluedroid_init(); if (ret) { printf("%s init bluetooth failed: %s\n", __func__, esp_err_to_name(ret)); return;} ret = esp_bluedroid_enable(); if (ret) { printf("%s enable bluetooth failed: %s\n", __func__, esp_err_to_name(ret)); return;} //register the callback function to the gap module ret = esp_ble_gap_register_callback(esp_gap_cb); if (ret){ printf("%s gap register error, error code = %x\n", __func__, ret); return; } BLE_Scan(); // while(1) // { // vTaskDelay(pdMS_TO_TICKS(150)); // } vTaskDelete(NULL); } uint16_t BLE_Scan(void) { esp_ble_scan_params_t scan_params = { .scan_type = BLE_SCAN_TYPE_ACTIVE, .own_addr_type = BLE_ADDR_TYPE_RPA_PUBLIC, .scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL, .scan_interval = 0x50, .scan_window = 0x30, .scan_duplicate = BLE_SCAN_DUPLICATE_DISABLE }; ESP_ERROR_CHECK(esp_ble_gap_set_scan_params(&scan_params)); printf("Starting BLE scan...\n"); ESP_ERROR_CHECK(esp_ble_gap_start_scanning(SCAN_DURATION)); // Set scanning duration vTaskDelay(SCAN_DURATION * 1000 / portTICK_PERIOD_MS); printf("Stopping BLE scan...\n"); // ESP_ERROR_CHECK(esp_ble_gap_stop_scanning()); ESP_ERROR_CHECK(esp_ble_dtm_stop()); BLE_Scan_Finish = 1; if(WiFi_Scan_Finish == 1) Scan_finish = 1; return BLE_NUM; } // 下面是新增的实现 static EventGroupHandle_t s_wifi_event_group; #define WIFI_CONNECTED_BIT BIT0 #define WIFI_FAIL_BIT BIT1 static const char *TAG = "WiFi_UTIL"; /* --------------------------- 事件回调 --------------------------- */ static void 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_DISCONNECTED) { xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT); } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT); } } /* --------------------------- 自动连接 --------------------------- */ bool WiFi_AutoConnect(const char *ssid, const char *password, uint8_t max_retry) { if (s_wifi_event_group == NULL) { s_wifi_event_group = xEventGroupCreate(); } /* 注册一次性事件监听 */ ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &event_handler, NULL, NULL)); ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL, NULL)); wifi_config_t wifi_config = { 0 }; strncpy((char *)wifi_config.sta.ssid, ssid, sizeof(wifi_config.sta.ssid)); strncpy((char *)wifi_config.sta.password, password, sizeof(wifi_config.sta.password)); wifi_config.sta.threshold.authmode = WIFI_AUTH_WPA2_PSK; ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config)); uint8_t retry_cnt = 0; while (retry_cnt <= max_retry) { ESP_LOGI(TAG, "WiFi connect attempt %u/%u to \"%s\"", retry_cnt + 1, max_retry + 1, ssid); xEventGroupClearBits(s_wifi_event_group, WIFI_CONNECTED_BIT | WIFI_FAIL_BIT); esp_wifi_connect(); EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group, WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, pdFALSE, pdFALSE, pdMS_TO_TICKS(6000)); /* 6 秒超时 */ if (bits & WIFI_CONNECTED_BIT) { ESP_LOGI(TAG, "WiFi connected"); goto success; } /* 失败,准备重试 */ retry_cnt++; } ESP_LOGE(TAG, "WiFi connect failed after %u retries", max_retry + 1); return false; success: return true; } /* --------------------------- 断开连接 --------------------------- */ esp_err_t WiFi_Disconnect(void) { ESP_LOGI(TAG, "Disconnecting WiFi..."); return esp_wifi_disconnect(); } // 获取WiFi AP列表 uint16_t wireless_get_wifi_ap_list(wifi_ap_info_t *ap_list, uint16_t max_aps) { if (!wifi_ap_list || wifi_ap_count == 0) { return 0; } uint16_t copy_count = (wifi_ap_count < max_aps) ? wifi_ap_count : max_aps; memcpy(ap_list, wifi_ap_list, copy_count * sizeof(wifi_ap_info_t)); return copy_count; } // 获取BLE设备列表 uint16_t wireless_get_ble_device_list(ble_device_info_t *device_list, uint16_t max_devices) { if (!ble_device_list || BLE_NUM == 0) { return 0; } uint16_t copy_count = (BLE_NUM < max_devices) ? BLE_NUM : max_devices; memcpy(device_list, ble_device_list, copy_count * sizeof(ble_device_info_t)); return copy_count; } // 打印所有WiFi AP信息 void wireless_print_wifi_aps(void) { if (!wifi_ap_list || wifi_ap_count == 0) { printf("No WiFi APs found or scan not completed\n"); return; } printf("Found %d WiFi APs:\n", wifi_ap_count); for (int i = 0; i < wifi_ap_count; i++) { printf(" %d: SSID: %s, BSSID: %02X:%02X:%02X:%02X:%02X:%02X, RSSI: %d, Auth: %d\n", i + 1, wifi_ap_list[i].ssid, wifi_ap_list[i].bssid[0], wifi_ap_list[i].bssid[1], wifi_ap_list[i].bssid[2], wifi_ap_list[i].bssid[3], wifi_ap_list[i].bssid[4], wifi_ap_list[i].bssid[5], wifi_ap_list[i].rssi, wifi_ap_list[i].authmode); } } // 打印所有BLE设备信息 void wireless_print_ble_devices(void) { if (!ble_device_list || BLE_NUM == 0) { printf("No BLE devices found or scan not completed\n"); return; } printf("Found %d BLE devices:\n", BLE_NUM); for (int i = 0; i < BLE_NUM; i++) { printf(" %d: Name: %s, Address: %02X:%02X:%02X:%02X:%02X:%02X, RSSI: %d\n", i + 1, ble_device_list[i].name, ble_device_list[i].address[0], ble_device_list[i].address[1], ble_device_list[i].address[2], ble_device_list[i].address[3], ble_device_list[i].address[4], ble_device_list[i].address[5], ble_device_list[i].rssi); } }