]> Git Repo - serial.git/blame - src/serial_listener.cc
Fixed some memory problems on destruction. Serial listener maybe working, serial...
[serial.git] / src / serial_listener.cc
CommitLineData
318bce46 1#include "serial/serial_listener.h"
313b0198
WW
2
3/***** Inline Functions *****/
4
5inline void defaultWarningCallback(const std::string& msg) {
6 std::cout << "SerialListener Warning: " << msg << std::endl;
7}
8
9inline void defaultDebugCallback(const std::string& msg) {
10 std::cout << "SerialListener Debug: " << msg << std::endl;
11}
12
13inline void defaultInfoCallback(const std::string& msg) {
14 std::cout << "SerialListener Info: " << msg << std::endl;
15}
16
17inline void defaultExceptionCallback(const std::exception &error) {
18 std::cerr << "SerialListener Unhandled Exception: " << error.what();
19 std::cerr << std::endl;
20 throw(error);
21}
22
7c0c9760
WW
23inline bool defaultComparator(const std::string &token) {
24 return true;
25}
26
313b0198
WW
27using namespace serial;
28
29/***** Listener Class Functions *****/
30
7c0c9760
WW
31void
32SerialListener::default_handler(const std::string &token) {
33 if (this->_default_handler)
34 this->_default_handler(token);
35}
36
37SerialListener::SerialListener() : listening(false), chunk_size(5) {
313b0198
WW
38 // Set default callbacks
39 this->handle_exc = defaultExceptionCallback;
40 this->info = defaultInfoCallback;
41 this->debug = defaultDebugCallback;
42 this->warn = defaultWarningCallback;
7c0c9760
WW
43
44 // Default handler stuff
45 this->_default_handler = NULL;
46 this->default_comparator = defaultComparator;
47 DataCallback tmp = boost::bind(&SerialListener::default_handler, this, _1);
48 this->default_filter = FilterPtr(new Filter(default_comparator, tmp));
49
318bce46
WW
50 // Set default tokenizer
51 this->setTokenizer(delimeter_tokenizer("\r"));
313b0198
WW
52}
53
54SerialListener::~SerialListener() {
51965cc5
WW
55 if (this->listening) {
56 this->stopListening();
57 }
58}
59
60void
61SerialListener::callback() {
62 try {
7c0c9760
WW
63 // <filter id, token>
64 std::pair<FilterPtr,TokenPtr> pair;
51965cc5
WW
65 while (this->listening) {
66 if (this->callback_queue.timed_wait_and_pop(pair, 10)) {
48a30ec4
WW
67 std::cout << "Got something off the callback queue: ";
68 std::cout << (*pair.second) << std::endl;
51965cc5 69 if (this->listening) {
51965cc5 70 try {
7c0c9760 71 pair.first->callback((*pair.second));
51965cc5
WW
72 } catch (std::exception &e) {
73 this->handle_exc(e);
74 }// try callback
75 } // if listening
51965cc5
WW
76 } // if popped
77 } // while (this->listening)
78 } catch (std::exception &e) {
79 this->handle_exc(SerialListenerException(e.what()));
80 }
313b0198
WW
81}
82
318bce46 83void
709fa5e1 84SerialListener::startListening(Serial &serial_port) {
313b0198
WW
85 if (this->listening) {
86 throw(SerialListenerException("Already listening."));
87 return;
88 }
89 this->listening = true;
90
709fa5e1 91 this->serial_port = &serial_port;
313b0198
WW
92 if (!this->serial_port->isOpen()) {
93 throw(SerialListenerException("Serial port not open."));
94 return;
95 }
96
97 listen_thread = boost::thread(boost::bind(&SerialListener::listen, this));
51965cc5
WW
98
99 // Start the callback thread
100 callback_thread =
101 boost::thread(boost::bind(&SerialListener::callback, this));
313b0198
WW
102}
103
318bce46
WW
104void
105SerialListener::stopListening() {
106 // Stop listening and clear buffers
313b0198 107 listening = false;
51965cc5 108
313b0198 109 listen_thread.join();
51965cc5
WW
110 callback_thread.join();
111
51965cc5 112 this->data_buffer = "";
313b0198 113 this->serial_port = NULL;
318bce46
WW
114
115 // Delete all the filters
dfd1837c 116 this->removeAllFilters();
318bce46
WW
117}
118
51965cc5
WW
119size_t
120SerialListener::determineAmountToRead() {
121 // TODO: Make a more intelligent method based on the length of the things
7c0c9760 122 // filters are looking for. e.g.: if the filter is looking for 'V=XX\r'
51965cc5 123 // make the read amount at least 5.
7c0c9760 124 return this->chunk_size;
313b0198
WW
125}
126
318bce46 127void
51965cc5 128SerialListener::readSomeData(std::string &temp, size_t this_many) {
313b0198
WW
129 // Make sure there is a serial port
130 if (this->serial_port == NULL) {
131 this->handle_exc(SerialListenerException("Invalid serial port."));
132 }
133 // Make sure the serial port is open
134 if (!this->serial_port->isOpen()) {
135 this->handle_exc(SerialListenerException("Serial port not open."));
136 }
51965cc5 137 temp = this->serial_port->read(this_many);
48a30ec4 138 std::cout << "Read(" << temp.length() << "): " << temp << std::endl;
313b0198
WW
139}
140
51965cc5 141void
7c0c9760 142SerialListener::filterNewTokens (std::vector<TokenPtr> new_tokens) {
51965cc5 143 // Iterate through the filters, checking each against new tokens
7c0c9760
WW
144 boost::mutex::scoped_lock lock(filter_mux);
145 std::vector<FilterPtr>::iterator it;
51965cc5 146 for (it=filters.begin(); it!=filters.end(); it++) {
7c0c9760 147 this->filter((*it), new_tokens);
51965cc5 148 } // for (it=filters.begin(); it!=filters.end(); it++)
51965cc5
WW
149}
150
7c0c9760
WW
151// <filter_ptr,token_ptr>
152void
153SerialListener::filter (FilterPtr filter, std::vector<TokenPtr> &tokens)
709fa5e1 154{
51965cc5 155 // Iterate through the token uuids and run each against the filter
7c0c9760
WW
156 std::vector<TokenPtr>::iterator it;
157 for (it=tokens.begin(); it!=tokens.end(); it++) {
158 TokenPtr token = (*it);
159 if (filter->comparator((*token)))
160 callback_queue.push(std::make_pair(filter,token));
51965cc5 161 }
313b0198
WW
162}
163
51965cc5
WW
164void
165SerialListener::listen() {
166 try {
167 while (this->listening) {
168 // Read some data
169 std::string temp;
170 this->readSomeData(temp, determineAmountToRead());
171 // If nothing was read then we
172 // don't need to iterate through the filters
173 if (temp.length() != 0) {
174 // Add the new data to the buffer
175 this->data_buffer += temp;
176 // Call the tokenizer on the updated buffer
7c0c9760 177 std::vector<TokenPtr> new_tokens;
51965cc5 178 this->tokenize(this->data_buffer, new_tokens);
51965cc5 179 // Run the new tokens through existing filters
7c0c9760 180 this->filterNewTokens(new_tokens);
51965cc5 181 }
51965cc5
WW
182 // Done parsing lines and buffer should now be set to the left overs
183 } // while (this->listening)
184 } catch (std::exception &e) {
185 this->handle_exc(SerialListenerException(e.what()));
186 }
313b0198
WW
187}
188
7c0c9760 189/***** Filter Functions *****/
709fa5e1 190
7c0c9760 191FilterPtr
dfd1837c
WW
192SerialListener::createFilter(ComparatorType comparator, DataCallback callback)
193{
7c0c9760 194 FilterPtr filter_ptr(new Filter(comparator, callback));
313b0198 195
7c0c9760
WW
196 boost::mutex::scoped_lock l(filter_mux);
197 this->filters.push_back(filter_ptr);
313b0198 198
7c0c9760
WW
199 return filter_ptr;
200}
51965cc5 201
dfd1837c
WW
202BlockingFilterPtr
203SerialListener::createBlockingFilter(ComparatorType comparator) {
204 return BlockingFilterPtr(
48a30ec4 205 new BlockingFilter(comparator, (*this)));
dfd1837c 206}
313b0198 207
dfd1837c
WW
208BufferedFilterPtr
209SerialListener::createBufferedFilter(ComparatorType comparator,
210 size_t buffer_size)
7c0c9760 211{
dfd1837c 212 return BufferedFilterPtr(
48a30ec4 213 new BufferedFilter(comparator, buffer_size, (*this)));
7c0c9760 214}
313b0198 215
dfd1837c
WW
216void
217SerialListener::removeFilter(FilterPtr filter_ptr) {
218 boost::mutex::scoped_lock l(filter_mux);
219 filters.erase(std::find(filters.begin(),filters.end(),filter_ptr));
313b0198
WW
220}
221
dfd1837c
WW
222void
223SerialListener::removeFilter(BlockingFilterPtr blocking_filter) {
224 this->removeFilter(blocking_filter->filter_ptr);
51965cc5
WW
225}
226
227void
dfd1837c
WW
228SerialListener::removeFilter(BufferedFilterPtr buffered_filter) {
229 this->removeFilter(buffered_filter->filter_ptr);
709fa5e1
WW
230}
231
7c0c9760 232void
dfd1837c 233SerialListener::removeAllFilters() {
7c0c9760
WW
234 boost::mutex::scoped_lock l(filter_mux);
235 filters.clear();
236 callback_queue.clear();
709fa5e1
WW
237}
238
This page took 0.050664 seconds and 4 git commands to generate.