ENTS-tock
Environmental NeTworked Sensor firmware on Tock OS
Loading...
Searching...
No Matches
module_handler.cpp
Go to the documentation of this file.
1#include "module_handler.hpp"
2
3#include <Arduino.h>
4#include <ArduinoLog.h>
5#include <Wire.h>
7
8#include <cstring>
9
11
13
15 // add module to map based on type
16 int type = module->Type();
17 req_map[type] = module;
18}
19
21 // remove module from map
22 req_map.erase(type);
23}
24
26 Log.traceln("ModuleHandler::OnReceive");
27
28 if (receive_buffer.len + num_bytes > receive_buffer.size) {
29 // TODO(jmadden173) handle error
30 }
31
32#ifdef UNIT_TEST
33 // Store pointer to the rx buffer
34 uint8_t* module_handler_rx_buffer_idx = module_handler_rx_buffer;
35 // get msg end flag
36 bool msg_end = module_handler_rx_buffer_idx;
37 // increment idx
38 ++module_handler_rx_buffer_idx;
39#else
40 // set continue flag to first byte
41 bool msg_end = static_cast<bool>(Wire.read());
42 Log.verboseln("msg_end: %T", msg_end);
43#endif
44
45 // get end of buffer
46 uint8_t* prev_end = NULL;
47 if (receive_buffer.len == 0) {
48 prev_end = receive_buffer.data;
49 } else {
50 prev_end = receive_buffer.data + receive_buffer.len;
51 }
52
53 // loop over available bytes in buffer
54 for (uint8_t* end = prev_end; end < prev_end + num_bytes - 1; end++) {
55#ifdef UNIT_TEST
56 // copy bytes
57 *end = *module_handler_rx_buffer_idx;
58 // increment idx
59 module_handler_rx_buffer_idx++;
60#else
61 // check if available
62 if (!Wire.available()) {
63 Log.errorln("Specified number of bytes is not available");
64 }
65
66 // read data
67 *end = Wire.read();
68#endif
69
70 Log.verboseln("Wire.read -> %X", *end);
71
72 // increment length
73 receive_buffer.len++;
74 }
75
76 // call module OnReceive
77 if (msg_end) {
78 Log.traceln("Message done");
79 Log.traceln("Decoding message");
80 for (int i = 0; i < receive_buffer.len; i++) {
81 Log.verboseln("receive_buffer[%d] = %X", i, receive_buffer.data[i]);
82 }
83
84 // decode measurement
85 Esp32Command cmd =
86 DecodeEsp32Command(receive_buffer.data, receive_buffer.len);
87
88 Log.verboseln("Forwarding message to: cmd.which_command: %d",
89 cmd.which_command);
90
91 // store reference to module for future OnRequest calls
92 if (req_map.find(cmd.which_command) == req_map.end()) {
93 Log.errorln("No module registered for command type: %d",
94 cmd.which_command);
95
96 // reset buffer
97 receive_buffer.len = 0;
98 receive_buffer.idx = 0;
99 return;
100 }
101
102 last_module = req_map.at(cmd.which_command);
103
104 // forward command to module
105 last_module->OnReceive(cmd);
106
107 // reset buffer
108 receive_buffer.len = 0;
109 receive_buffer.idx = 0;
110 }
111}
112
114 Log.traceln("ModuleHandler::OnRequest");
115
116 // only call module if nothing in buffer
117 if (request_buffer.len == 0) {
118 Log.traceln("Copy data into the request buffer");
119 // forward request to last module received
120 request_buffer.len = last_module->OnRequest(request_buffer.data);
121 Log.traceln("Done processing OnRequest");
122 Log.traceln("Buffer length: %d", request_buffer.len);
123 }
124
125 // check if we should send length
126 if (send_length) {
127 Log.traceln("Sending length %d", request_buffer.len);
128
129 // send in little-endian
130 uint8_t len_bytes[2] = {};
131 len_bytes[1] = (uint8_t)request_buffer.len & 0xFF;
132 len_bytes[0] = (uint8_t)((request_buffer.len >> 8) & 0xFF);
133
134 Log.verboseln("len_bytes = {%X, %X}", len_bytes[0], len_bytes[1]);
135
136 // write to buffer
137 Wire.write(len_bytes, sizeof(len_bytes));
138
139 Log.traceln("Successfully sent length");
140
141 // set flag that length was sent
142 send_length = false;
143
144 // otherwise send data
145 } else {
146 Log.traceln("Sending data");
150 static const int wire_buffer_size = 32;
151
152 // get number of bytes remaining
153 size_t bytes_remaining = request_buffer.len - request_buffer.idx;
154 Log.traceln("Bytes remaining: %d", bytes_remaining);
155
156 // print entire buffer
157 // for (int i = 0; i < request_buffer.len; i++) {
158 // Log.verboseln("request_buffer[%d] = %X", request_buffer.idx,
159 // request_buffer.data[i]);
160 //}
161
162 bool finished = bytes_remaining < wire_buffer_size - 1;
163 size_t bytes_to_send = 0;
164
165 // write flag indicating if we are finished
166 if (finished) {
167 Log.traceln("Writing with finished flag");
168 // write finished flag
169 Wire.write(1);
170
171 bytes_to_send = bytes_remaining;
172 } else {
173 Log.traceln("Writing with not finished flag");
174 // write unfinished flag
175 Wire.write(0);
176
177 bytes_to_send = wire_buffer_size - 1;
178 }
179
180 // find the end of pr
181 uint8_t* end = request_buffer.data + request_buffer.idx;
182
183 // print what will be sent
184 for (int i = 0; i < bytes_to_send; i++) {
185 Log.verboseln("request_buffer[%d] = %X", request_buffer.idx + i, end[i]);
186 }
187
188 Wire.write(end, bytes_to_send);
189
190 request_buffer.idx += bytes_to_send;
191
192 // cleanup after finished
193 if (finished) {
194 // reset to indicate flushed buffer
195 request_buffer.len = 0;
196 request_buffer.idx = 0;
197
198 // set flag to send length when complate
199 send_length = true;
200 }
201 }
202}
203
205 return req_map.at(type);
206}
207
209 // call Reset() for all modules in req_map
210 for (auto& entry : req_map) {
211 entry.second->Reset();
212 }
213}
Module * GetModule(int type)
Get the module associated with a specific message type.
void OnReceive(size_t num_bytes)
Arduino I2C onRecieve.
void RegisterModule(Module *module)
Register a module with a message type.
~ModuleHandler()
Destroy the Module Handler object.
void ResetModules(void)
Resets all modules.
ModuleHandler()
Construct a new Module Handler object.
void DeregisterModule(int type)
Deregister a module.
void OnRequest(void)
Arduino I2C onRequest.
Class prototype for modules.
void Reset(void)
Resets the module to default state.
uint8_t i
Esp32Command DecodeEsp32Command(const uint8_t *data, const size_t len)
Decodes an Esp32Command message.
Definition transcoder.c:246
Interface for controlling the esp32.
Library for encoding/decoding protobuf messages.