Krolyxon
Commit bd12e09

Branches

Tags

Refs →

orion-rffirmwareblescanner.cpp

209 lines · 4.9 KB · C++

1#include <Arduino.h>
2#include <BLEDevice.h>
3#include <BLEScan.h>
4#include <BLEAdvertisedDevice.h>
5#include <vector>
6
7#include "display.h"
8#include "buttons.h"
9#include "config.h"
10
11// ===== DEVICE STRUCT =====
12struct BLEDeviceInfo {
13 String name;
14 String address;
15 int rssi;
16 String manufacturer;
17 String deviceType;
18};
19
20static std::vector<BLEDeviceInfo> devices;
21static BLEScan *pBLEScan;
22static int selectedIndex = 0;
23
24// ===== CALLBACK =====
25class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks {
26 void onResult(BLEAdvertisedDevice advertisedDevice) override {
27 BLEDeviceInfo dev;
28
29 String tempName = advertisedDevice.getName();
30
31 if (tempName.length() == 0 && advertisedDevice.haveServiceData()) {
32 tempName = advertisedDevice.getServiceData().c_str();
33 }
34
35 if (tempName.length() == 0) {
36 String addr = advertisedDevice.getAddress().toString().c_str();
37 tempName = "BLE_" + addr.substring(addr.length() - 5);
38 }
39
40 dev.name = tempName;
41 dev.address = advertisedDevice.getAddress().toString().c_str();
42 dev.rssi = advertisedDevice.getRSSI();
43
44 if (advertisedDevice.haveManufacturerData()) {
45 String mData = advertisedDevice.getManufacturerData().c_str();
46
47 if (mData.length() >= 2) {
48 char buffer[10];
49 sprintf(buffer, "0x%02X%02X",
50 (uint8_t)mData[1],
51 (uint8_t)mData[0]);
52 dev.manufacturer = String(buffer);
53 } else {
54 dev.manufacturer = "unknown";
55 }
56 } else {
57 dev.manufacturer = "unknown";
58 }
59
60 if (advertisedDevice.haveServiceUUID()) {
61 dev.deviceType =
62 advertisedDevice.getServiceUUID().toString().c_str();
63 } else {
64 dev.deviceType = "unknown";
65 }
66
67 devices.push_back(dev);
68 }
69};
70
71// ===== DRAW MENU =====
72void ble_drawMenu()
73{
74 u8g2.clearBuffer();
75
76 if (devices.empty())
77 {
78 u8g2.setFont(u8g2_font_6x12_tr);
79 u8g2.drawStr(0, 30, "No devices");
80 u8g2.drawStr(0, 45, "Press BACK");
81 }
82 else
83 {
84 u8g2.setFont(u8g2_font_5x8_tr);
85
86 char counter[20];
87 sprintf(counter, "%d/%d", selectedIndex + 1, (int)devices.size());
88 u8g2.drawStr(0, 8, counter);
89
90 u8g2.setFont(u8g2_font_6x10_tr);
91
92 for (int i = 0; i < 3; i++)
93 {
94 int idx = selectedIndex + i;
95 if (idx >= devices.size()) break;
96
97 int y = 22 + i * 14;
98
99 if (i == 0)
100 {
101 u8g2.drawBox(0, y - 10, 128, 12);
102 u8g2.setDrawColor(0);
103 }
104
105 String text = devices[idx].name;
106 if (text.length() > 12)
107 text = text.substring(0, 12) + "..";
108
109 text += " (" + String(devices[idx].rssi) + ")";
110
111 u8g2.drawStr(2, y, text.c_str());
112
113 if (i == 0)
114 u8g2.setDrawColor(1);
115 }
116 }
117
118 u8g2.sendBuffer();
119}
120
121// ===== DEVICE DETAILS =====
122void ble_drawDetails(const BLEDeviceInfo &dev)
123{
124 u8g2.clearBuffer();
125 u8g2.setFont(u8g2_font_5x8_tr);
126
127 u8g2.drawStr(0, 10, dev.name.c_str());
128 u8g2.drawStr(0, 20, dev.address.c_str());
129
130 char rssiStr[20];
131 sprintf(rssiStr, "RSSI: %d", dev.rssi);
132 u8g2.drawStr(0, 30, rssiStr);
133
134 u8g2.drawStr(0, 40, dev.manufacturer.c_str());
135
136 u8g2.sendBuffer();
137}
138
139// ===== SCAN =====
140void ble_scan()
141{
142 devices.clear();
143
144 u8g2.clearBuffer();
145 u8g2.drawStr(10, 30, "Scanning...");
146 u8g2.sendBuffer();
147
148 BLEDevice::init("");
149
150 pBLEScan = BLEDevice::getScan();
151 pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks(), false);
152 pBLEScan->setActiveScan(true);
153 pBLEScan->setInterval(100);
154 pBLEScan->setWindow(99);
155
156 pBLEScan->start(5, false);
157
158 // remove duplicates
159 std::vector<BLEDeviceInfo> unique;
160 for (auto &d : devices)
161 {
162 bool exists = false;
163 for (auto &u : unique)
164 {
165 if (u.address == d.address)
166 {
167 exists = true;
168 break;
169 }
170 }
171 if (!exists) unique.push_back(d);
172 }
173
174 devices = unique;
175}
176
177// ===== MAIN LOOP =====
178void ble_loop()
179{
180 static uint32_t lastPress = 0;
181
182 if (millis() - lastPress < 200)
183 return;
184
185 if (btnDown() && selectedIndex < (int)devices.size() - 1)
186 {
187 selectedIndex++;
188 ble_drawMenu();
189 lastPress = millis();
190 }
191 else if (btnUp() && selectedIndex > 0)
192 {
193 selectedIndex--;
194 ble_drawMenu();
195 lastPress = millis();
196 }
197 else if (btnSelect() && !devices.empty())
198 {
199 ble_drawDetails(devices[selectedIndex]);
200 delay(3000);
201 ble_drawMenu();
202 lastPress = millis();
203 }
204 else if (btnBack())
205 {
206 lastPress = millis();
207 return;
208 }
209}