-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
137 lines (110 loc) · 3.78 KB
/
main.cpp
File metadata and controls
137 lines (110 loc) · 3.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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
99
100
101
102
103
104
105
106
107
108
109
110
111
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
#include <boost/asio.hpp>
#include <atomic>
#include <chrono>
#include <iostream>
#include <string>
#include <thread>
using namespace boost::asio;
using namespace std::chrono_literals;
class BleuIOScanner {
public:
BleuIOScanner(const std::string& port_name, unsigned int baud_rate = 57600)
: io_(),
serial_(io_),
running_(false) {
serial_.open(port_name);
serial_.set_option(serial_port_base::baud_rate(baud_rate));
serial_.set_option(serial_port_base::character_size(8));
serial_.set_option(serial_port_base::parity(serial_port_base::parity::none));
serial_.set_option(serial_port_base::stop_bits(serial_port_base::stop_bits::one));
serial_.set_option(serial_port_base::flow_control(serial_port_base::flow_control::none));
}
~BleuIOScanner() {
stopReader();
if (serial_.is_open()) {
boost::system::error_code ec;
serial_.close(ec);
}
}
void startReader() {
if (running_) return;
running_ = true;
doRead();
io_thread_ = std::thread([this]() {
io_.run();
});
}
void stopReader() {
if (!running_) return;
running_ = false;
boost::system::error_code ec;
serial_.cancel(ec);
io_.stop();
if (io_thread_.joinable()) {
io_thread_.join();
}
}
void sendCommand(const std::string& cmd) {
std::string full = cmd + "\r\n";
write(serial_, buffer(full));
}
private:
void doRead() {
serial_.async_read_some(
buffer(read_buf_, sizeof(read_buf_)),
[this](const boost::system::error_code& ec, std::size_t bytes_transferred) {
if (!ec) {
std::string data(read_buf_, bytes_transferred);
std::cout << data << std::flush;
if (running_) {
doRead();
}
} else {
if (running_ && ec != boost::asio::error::operation_aborted) {
std::cerr << "\nRead error: " << ec.message() << std::endl;
}
}
});
}
private:
io_context io_;
serial_port serial_;
std::thread io_thread_;
std::atomic<bool> running_;
char read_buf_[1024];
};
int main() {
try {
std::string port_name;
int seconds = 3;
port_name ="/dev/cu.usbmodem4048FDE52CF21";
/* std::cout << "Enter BleuIO serial port (example: /dev/cu.usbmodemXXXX): ";
std::getline(std::cin, port_name); */
std::cout << "Enter scan duration in seconds: ";
std::cin >> seconds;
if (seconds <= 0) {
std::cerr << "Scan duration must be greater than 0." << std::endl;
return 1;
}
BleuIOScanner bleuio(port_name);
std::cout << "\nConnected to " << port_name << std::endl;
std::cout << "\nStarting reader...\n" << std::endl;
bleuio.startReader();
// Small delay so reader is ready
std::this_thread::sleep_for(300ms);
std::cout << "\nPutting BleuIO in Central role...\n" << std::endl;
bleuio.sendCommand("AT+CENTRAL");
std::this_thread::sleep_for(1s);
std::cout << "\nScanning for " << seconds << " second(s)...\n" << std::endl;
bleuio.sendCommand("AT+GAPSCAN=" + std::to_string(seconds));
// Wait slightly longer than scan duration so output can complete
std::this_thread::sleep_for(std::chrono::seconds(seconds) + 2s);
std::cout << "\nScan finished.\n" << std::endl;
bleuio.stopReader();
}
catch (const std::exception& ex) {
std::cerr << "Error: " << ex.what() << std::endl;
return 1;
}
return 0;
}