Skip to content

Commit d33468a

Browse files
Add files via upload
1 parent eae9615 commit d33468a

4 files changed

Lines changed: 206 additions & 97 deletions

File tree

ArduinoStrike/ArduinoStrike/Arduino.cpp

Lines changed: 157 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "Arduino.h"
2+
#include "Utils.h"
23

34
Arduino::~Arduino()
45
{
@@ -71,115 +72,204 @@ Arduino::Arduino(LPCSTR name) : handle(INVALID_HANDLE_VALUE)
7172
cout << "Successfully connected!" << endl;
7273
}
7374

74-
bool Arduino::IsAvailable() const
75-
{
76-
DWORD errors;
77-
COMSTAT status;
78-
79-
if (!ClearCommError(handle, &errors, &status))
80-
{
81-
LOG("Error checking available data: " + to_string(GetLastError()));
82-
return false;
83-
}
84-
85-
return status.cbInQue > 0;
86-
}
87-
8875
bool Arduino::GetDevice(LPCSTR name, LPSTR port)
8976
{
90-
bool status = false;
9177
HDEVINFO device_info = SetupDiGetClassDevs(&GUID_DEVCLASS_PORTS, NULL, NULL, DIGCF_PRESENT);
9278

9379
if (device_info == INVALID_HANDLE_VALUE)
9480
{
95-
LOG("Failed to get device information.");
81+
LOG("Failed to get device information (SetupDiGetClassDevs returned INVALID_HANDLE_VALUE).");
9682
return false;
9783
}
9884

99-
DWORD count = 0;
100-
SP_DEVINFO_DATA dev_info_data = {};
101-
dev_info_data.cbSize = sizeof(dev_info_data);
102-
LOG("Searching for device: " + string(name));
103-
104-
struct DeviceInfo
85+
vector<DeviceInfo> devices;
86+
vector<regex> patterns =
10587
{
106-
string port;
107-
string hardware_id;
108-
string friendly_name;
88+
regex("VID_2341&PID_.*"),
89+
regex("VID_2A03&PID_.*"),
90+
regex("VID_1A86&PID_.*")
10991
};
11092

111-
vector<DeviceInfo> devices;
112-
vector<regex> patterns = { regex("VID_2341&PID_.*"), regex("VID_1A86&PID_.*"), regex("VID_10C4&PID_.*") };
93+
// Load configuration
94+
DeviceInfo config_device;
95+
bool found_device = false;
96+
bool config_loaded = Arduino::LoadConfiguration("device_config.cfg", config_device);
97+
98+
// Collect system devices
99+
LOG("Enumerating connected devices...");
100+
DWORD count = 0;
101+
SP_DEVINFO_DATA dev_info_data = {};
102+
dev_info_data.cbSize = sizeof(dev_info_data);
113103

114-
// Step 1: Collecting all devices
115104
while (SetupDiEnumDeviceInfo(device_info, count++, &dev_info_data))
116105
{
117-
DeviceInfo info;
118-
BYTE buffer[256];
106+
DeviceInfo system_device;
119107

120-
// Reading FRIENDLYNAME
121-
if (SetupDiGetDeviceRegistryProperty(device_info, &dev_info_data, SPDRP_FRIENDLYNAME, NULL, buffer, sizeof(buffer), NULL))
108+
if (Arduino::ExtractProperties(device_info, dev_info_data, system_device))
122109
{
123-
info.friendly_name = string((LPCSTR)buffer);
124-
LOG("Device detected with FRIENDLYNAME: " + info.friendly_name);
110+
devices.push_back(system_device);
111+
LOG("Detected device: FRIENDLYNAME = " + system_device.friendly_name + ", HARDWAREID = " + system_device.hardware_id + ", PORT = " + system_device.port);
112+
113+
// Check against configuration file
114+
if (config_loaded && system_device.friendly_name == config_device.friendly_name && system_device.hardware_id == config_device.hardware_id)
115+
{
116+
strncpy_s(port, 100, system_device.port.c_str(), system_device.port.size());
117+
LOG("Using saved device: FRIENDLYNAME = " + system_device.friendly_name + ", HARDWAREID = " + system_device.hardware_id + ", PORT = " + system_device.port);
118+
found_device = true;
119+
break;
120+
}
125121

126-
// Reading PORT
127-
LPCSTR start = strchr((LPCSTR)buffer, '(');
128-
LPCSTR end = strchr((LPCSTR)buffer, ')');
122+
// Check against VID/PID patterns or name
123+
if (!found_device && name && system_device.friendly_name.find(name) != string::npos)
124+
{
125+
strncpy_s(port, 100, system_device.port.c_str(), system_device.port.size());
126+
LOG("Device matched by FRIENDLYNAME: " + system_device.friendly_name);
127+
found_device = true;
128+
break;
129+
}
129130

130-
if (start && end && end > start)
131+
for (const auto& pattern : patterns)
131132
{
132-
info.port = string(start + 1, end - start - 1);
133+
if (regex_search(system_device.hardware_id, pattern))
134+
{
135+
strncpy_s(port, 100, system_device.port.c_str(), system_device.port.size());
136+
LOG("Device matched by VID/PID: " + system_device.hardware_id);
137+
found_device = true;
138+
break;
139+
}
133140
}
134141
}
135142

136-
// Reading HARDWAREID
137-
if (SetupDiGetDeviceRegistryProperty(device_info, &dev_info_data, SPDRP_HARDWAREID, NULL, buffer, sizeof(buffer), NULL))
143+
if (found_device)
144+
break;
145+
}
146+
147+
SetupDiDestroyDeviceInfoList(device_info);
148+
149+
// Handle case where no device was found
150+
if (!found_device)
151+
{
152+
if (config_loaded)
153+
{
154+
LOG("Saved device not found in the system. Deleting configuration file.");
155+
remove("device_config.cfg");
156+
}
157+
158+
if (devices.empty())
138159
{
139-
info.hardware_id = string((LPCSTR)buffer);
140-
LOG("Device detected with HARDWAREID: " + info.hardware_id);
160+
LOG("No devices found in the system.");
161+
return false;
141162
}
142163

143-
devices.push_back(info);
164+
LOG("Prompting user to select a device...");
165+
return Arduino::SelectDevice(devices, port);
144166
}
145167

146-
SetupDiDestroyDeviceInfoList(device_info);
168+
return true;
169+
}
147170

148-
// Step 2: Checking and selecting the device
149-
for (const auto& device : devices)
171+
bool Arduino::LoadConfiguration(const string& file_name, DeviceInfo& config_device)
172+
{
173+
string line;
174+
ifstream config(file_name);
175+
176+
if (!config)
150177
{
151-
LOG("Evaluating device: FRIENDLYNAME = " + device.friendly_name + ", HARDWAREID = " + device.hardware_id);
178+
LOG("Configuration file not found.");
179+
return false;
180+
}
152181

153-
// If the name is specified, check it
154-
if (name && !device.friendly_name.empty() && device.friendly_name.find(name) != string::npos)
182+
while (getline(config, line))
183+
{
184+
if (line.find("FRIENDLYNAME=") == 0)
155185
{
156-
strncpy_s(port, 100, device.port.c_str(), device.port.size());
157-
LOG("Device matched by FRIENDLYNAME: " + device.friendly_name);
158-
status = true;
159-
break;
186+
config_device.friendly_name = line.substr(13);
187+
}
188+
else if (line.find("HARDWAREID=") == 0)
189+
{
190+
config_device.hardware_id = line.substr(11);
160191
}
192+
else if (line.find("PORT=") == 0)
193+
{
194+
config_device.port = line.substr(5);
195+
}
196+
}
197+
198+
if (!config_device.friendly_name.empty() && !config_device.hardware_id.empty())
199+
{
200+
LOG("Loaded device from configuration: FRIENDLYNAME = " + config_device.friendly_name + ", HARDWAREID = " + config_device.hardware_id + ", PORT = " + config_device.port);
201+
return true;
202+
}
203+
204+
LOG("Configuration file is incomplete or corrupted.");
205+
return false;
206+
}
207+
208+
bool Arduino::ExtractProperties(HDEVINFO device_info, SP_DEVINFO_DATA& dev_info_data, DeviceInfo& device)
209+
{
210+
BYTE buffer[256];
161211

162-
// If the name does not match, check the VID/PID
163-
for (const auto& pattern : patterns)
212+
if (SetupDiGetDeviceRegistryProperty(device_info, &dev_info_data, SPDRP_FRIENDLYNAME, NULL, buffer, sizeof(buffer), NULL))
213+
{
214+
device.friendly_name = string((LPCSTR)buffer);
215+
216+
LPCSTR start = strchr((LPCSTR)buffer, '(');
217+
LPCSTR end = strchr((LPCSTR)buffer, ')');
218+
219+
if (start && end && end > start)
164220
{
165-
if (!device.hardware_id.empty() && regex_search(device.hardware_id, pattern))
166-
{
167-
strncpy_s(port, 100, device.port.c_str(), device.port.size());
168-
LOG("Device matched by VID/PID: " + device.hardware_id);
169-
status = true;
170-
break;
171-
}
221+
device.port = string(start + 1, end - start - 1);
172222
}
223+
}
173224

174-
if (status) break;
225+
if (SetupDiGetDeviceRegistryProperty(device_info, &dev_info_data, SPDRP_HARDWAREID, NULL, buffer, sizeof(buffer), NULL))
226+
{
227+
device.hardware_id = string((LPCSTR)buffer);
175228
}
176229

177-
if (!status)
230+
return !device.friendly_name.empty() && !device.hardware_id.empty();
231+
}
232+
233+
bool Arduino::SelectDevice(const vector<DeviceInfo>& devices, LPSTR port)
234+
{
235+
Utils utils;
236+
utils.PrintCenteredText("The following devices were detected:");
237+
238+
for (size_t i = 0; i < devices.size(); ++i)
178239
{
179-
LOG("No matching device found.");
240+
string device_info = "[" + to_string(i + 1) + "] FRIENDLYNAME: " + devices[i].friendly_name + ", HARDWAREID: " + devices[i].hardware_id + ", PORT: " + devices[i].port;
241+
utils.PrintCenteredText(device_info);
180242
}
181243

182-
return status;
244+
utils.PrintCenteredText("Please select the device you want to use by entering its number (0 to cancel): ", false);
245+
246+
int choice;
247+
cin >> choice;
248+
249+
if (choice > 0 && choice <= static_cast<int>(devices.size()))
250+
{
251+
const auto& selected_device = devices[choice - 1];
252+
strncpy_s(port, 100, selected_device.port.c_str(), selected_device.port.size());
253+
LOG("User selected device: " + selected_device.friendly_name);
254+
255+
ofstream config("device_config.cfg");
256+
257+
if (config)
258+
{
259+
config << "FRIENDLYNAME=" << selected_device.friendly_name << endl;
260+
config << "HARDWAREID=" << selected_device.hardware_id << endl;
261+
config << "PORT=" << selected_device.port << endl;
262+
263+
LOG("Device selection saved to configuration.");
264+
}
265+
266+
return true;
267+
}
268+
269+
utils.PrintCenteredText("No device selected by the user.");
270+
LOG("No device selected by the user.");
271+
272+
return false;
183273
}
184274

185275
bool Arduino::WriteMessage(const string& message) const

ArduinoStrike/ArduinoStrike/Arduino.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ using namespace std;
1919
using namespace chrono;
2020
using namespace this_thread;
2121

22+
struct DeviceInfo
23+
{
24+
string port;
25+
string hardware_id;
26+
string friendly_name;
27+
};
28+
2229
class Arduino
2330
{
2431
public:
@@ -28,7 +35,9 @@ class Arduino
2835

2936
private:
3037
HANDLE handle;
31-
bool IsAvailable() const;
3238
bool GetDevice(LPCSTR name, LPSTR port);
39+
bool LoadConfiguration(const string& file_name, DeviceInfo& config_device);
40+
bool ExtractProperties(HDEVINFO device_info, SP_DEVINFO_DATA& dev_info_data, DeviceInfo& device);
41+
bool SelectDevice(const vector<DeviceInfo>& devices, LPSTR port);
3342
static void LogMessage(const string& message);
3443
};

0 commit comments

Comments
 (0)