Newer
Older
#include <main.h>
#include "nvs.h"
#include "nvs_flash.h"
#include "esp_log.h"
#include "esp_sleep.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_bt.h"
#include "esp_bt_main.h"
#include "esp_gap_ble_api.h"
#include <string.h>
#include <string>
#include <unordered_set>
#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
static const char* TAG = "main";
std::unordered_set<std::string> devices;
uint8_t unique_pings = 0;
uint16_t total_pings = 0;
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
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,
// Set scan interval & window to 25ms (40 * 0.625)
.scan_interval = 0x28,
.scan_window = 0x28,
.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
);
void app_main(void) {
// Initialize NVS.
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();
ret = esp_bt_controller_init(&bt_cfg);
if (ret) {
ESP_LOGE(TAG, "%s initialize controller failed: %s\n",
__func__, esp_err_to_name(ret));
return;
}
ret = esp_bt_controller_enable(ESP_BT_MODE_BLE);
if (ret) {
ESP_LOGE(TAG, "%s enable controller failed: %s\n",
__func__, esp_err_to_name(ret));
return;
}
ret = esp_bluedroid_init();
if (ret) {
ESP_LOGE(TAG, "%s init bluetooth failed: %s\n",
__func__, esp_err_to_name(ret));
return;
}
ret = esp_bluedroid_enable();
if (ret) {
ESP_LOGE(TAG, "%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){
ESP_LOGE(TAG, "%s gap register failed, error code = %x\n", __func__, ret);
return;
}
// Set wakeup interval of 4s
esp_sleep_enable_timer_wakeup(4 * 1e6);
while (true) {
ret = esp_ble_gap_set_scan_params(&ble_scan_params);
if (ret){
ESP_LOGE(TAG, "set scan params error, error code = %x", ret);
}
unique_pings = 0;
total_pings = 0;
devices.clear();
// Set scan duration to 30s, we can control it with the delay below
esp_ble_gap_start_scanning(30);
vTaskDelay(pdMS_TO_TICKS(2000));
ESP_ERROR_CHECK(esp_ble_gap_stop_scanning());
ESP_LOGI(TAG, "[%s]: Unique devices captured: %u", __func__, unique_pings);
ESP_LOGI(TAG, "[%s]: Total pings captured: %u", __func__, total_pings);
vTaskDelay(2);
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
ESP_LOGI(TAG, "[%s]: Slep", __func__);
esp_light_sleep_start();
ESP_LOGI(TAG, "[%s]: Wakey", __func__);
}
}
static void esp_gap_cb(
esp_gap_ble_cb_event_t event,
esp_ble_gap_cb_param_t *param
) {
uint8_t *adv_name = NULL;
uint8_t adv_name_len = 0;
switch (event) {
case ESP_GAP_BLE_SCAN_START_COMPLETE_EVT:
//scan start complete event to indicate scan start successfully or failed
if (param->scan_start_cmpl.status != ESP_BT_STATUS_SUCCESS) {
ESP_LOGE(TAG, "scan start failed, error status = %x", param->scan_start_cmpl.status);
break;
}
ESP_LOGI(TAG, "scan start success");
break;
case ESP_GAP_BLE_SCAN_RESULT_EVT: {
esp_ble_gap_cb_param_t *scan_result = (esp_ble_gap_cb_param_t *)param;
switch (scan_result->scan_rst.search_evt) {
case ESP_GAP_SEARCH_INQ_RES_EVT: {
char mac[18];
auto addr = scan_result->scan_rst.bda;
snprintf(mac, 18, "%.2x %.2x %.2x %.2x %.2x %.2x",
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
adv_name = esp_ble_resolve_adv_data(
scan_result->scan_rst.ble_adv,
ESP_BLE_AD_TYPE_NAME_CMPL,
&adv_name_len
);
if (adv_name_len > 0 && strncmp(
(char*) adv_name, "INFOTECH", std::min(adv_name_len, (uint8_t) 8)
) == 0
) {
if (devices.find(mac) == devices.end()) {
devices.insert(mac);
unique_pings += 1;
ESP_LOGI(TAG, "%s (%ddBm, %.*s)",
mac, scan_result->scan_rst.rssi, adv_name_len, adv_name);
}
// Also count duplicates here
total_pings += 1;
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
ESP_LOGD(TAG, "%s", mac);
}
break;
}
case ESP_GAP_SEARCH_INQ_CMPL_EVT:
break;
default:
break;
}
break;
}
case ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT:
if (param->scan_stop_cmpl.status != ESP_BT_STATUS_SUCCESS){
ESP_LOGE(TAG, "scan stop failed, error status = %x", param->scan_stop_cmpl.status);
break;
}
ESP_LOGI(TAG, "stop scan successfully");
break;
case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT:
if (param->adv_stop_cmpl.status != ESP_BT_STATUS_SUCCESS){
ESP_LOGE(TAG, "adv stop failed, error status = %x", param->adv_stop_cmpl.status);
break;
}
ESP_LOGI(TAG, "stop adv successfully");
break;
default:
break;
}
}