-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPacketCommand.h
218 lines (199 loc) · 10.3 KB
/
PacketCommand.h
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
/**
* PacketCommand - A Wiring/Arduino library to
*
* Copyright (C) 2015 Craig Versek <[email protected]>
*
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PACKETCOMMAND_H
#define PACKETCOMMAND_H
#include <Arduino.h>
#include <Stream.h>
#include <stdint.h>
#include "PacketQueue.h"
#include "PacketShared.h"
// Uncomment the next line to run the library in debug mode (verbose messages)
//#define PACKETCOMMAND_DEBUG
#ifdef PACKETCOMMAND_DEBUG
#ifdef DEBUG_PORT
#define PACKETCOMMAND_DEBUG_PORT DEBUG_PORT
#else
#define PACKETCOMMAND_DEBUG_PORT Serial
#endif
#endif
typedef float float32_t;
typedef double float64_t;
typedef byte uint8_t;
/******************************************************************************/
// PacketCommand
// so that callbacks print
class PacketCommand{
public:
// Constants
static const size_t MAXCOMMANDS_DEFAULT = 10;
static const size_t MAX_TYPE_ID_LEN = 4;
static const size_t INPUTBUFFERSIZE_DEFAULT = 64; //FIXME zero means do not allocate
static const size_t OUTPUTBUFFERSIZE_DEFAULT = 64;
// Command/handler info structure
struct CommandInfo {
byte type_id[MAX_TYPE_ID_LEN]; //limited size type ID must be respected!
const char* name;
void (*function)(PacketCommand&); //handler callback function
};
// Command/handler info structure
struct InputProperties{
uint32_t from_addr;
uint32_t recv_timestamp;
int8_t RSSI;
};
// Constructor
PacketCommand(size_t maxCommands = MAXCOMMANDS_DEFAULT,
size_t inputBufferSize = INPUTBUFFERSIZE_DEFAULT,
size_t outputBufferSize = OUTPUTBUFFERSIZE_DEFAULT
);
PacketShared::STATUS reset();
PacketShared::STATUS addCommand(const byte* type_id,
const char* name,
void(*function)(PacketCommand&)); // Add a command to the processing dictionary.
PacketShared::STATUS registerDefaultHandler(void (*function)(PacketCommand&)); // A handler to call when no valid command received.
//registering callbacks for IO steps
//input
PacketShared::STATUS registerRecvCallback(bool (*function)(PacketCommand&));
PacketShared::STATUS registerReplySendCallback(void (*function)(PacketCommand&));
//output
PacketShared::STATUS registerSendCallback(bool (*function)(PacketCommand&)); // A callback which writes output to the interface
PacketShared::STATUS registerSendNonblockingCallback(void (*function)(PacketCommand&)); // A callback which schedules to writes output to the interface, returns immediately
PacketShared::STATUS registerSendBufferedCallback(void (*function)(PacketCommand&)); // A callback which schedules to writes output to the interface's buffer, returns immediately
PacketShared::STATUS registerReplyRecvCallback(bool (*function)(PacketCommand&));
PacketShared::STATUS processInput(); //receive input, match command, and dispatch
PacketShared::STATUS lookupCommandByName(const char* name); //lookup and set current command by name
CommandInfo getCurrentCommand();
PacketShared::STATUS recv(); // Use the '_recv_callback' to put data into _input_buffer
PacketShared::STATUS recv(bool& gotPacket); // Use the '_recv_callback' to put data into _input_buffer
PacketShared::STATUS set_recvTimestamp(uint32_t timestamp_micros);
uint32_t get_recvTimestamp(){return _recv_timestamp_micros;};
PacketShared::STATUS matchCommand(); // Read the packet header from the input buffer and locate a matching registered handler function
PacketShared::STATUS dispatchCommand(); // Call the current Command
PacketShared::STATUS send(); // Use the '_send_callback' to send _output_buffer
PacketShared::STATUS send(bool& sentPacket);// Use the '_send_callback' to send _output_buffer
PacketShared::STATUS send_nonblocking(); // Use the '_send_nonblocking_callback' to send _schedule the output_buffer contents to be sent, returning immediately
PacketShared::STATUS send_buffered(); // Use the '_send_buffered_callback' to send _schedule the output_buffer contents to be sent, returning immediately
PacketShared::STATUS set_sendTimestamp(uint32_t timestamp_micros);
PacketShared::STATUS reply_send();
PacketShared::STATUS reply_recv();
PacketShared::STATUS assignInputBuffer(byte* buff, size_t len);
void resetInputBuffer();
byte* getInputBuffer();
int getInputBufferIndex();
int getInputBufferSize(){return _inputBufferSize;};
size_t getInputLen(){return _input_len;};
PacketShared::STATUS setInputBufferIndex(int new_index);
PacketShared::STATUS moveInputBufferIndex(int n);
void setInputProperties(struct InputProperties props){_input_properties=props;};
struct InputProperties getInputProperties(){return _input_properties;};
PacketShared::STATUS enqueueInputBuffer(PacketQueue& pq);
PacketShared::STATUS dequeueInputBuffer(PacketQueue& pq);
byte* getOutputBuffer(){return _output_buffer;};
int getOutputBufferIndex();
int getOutputBufferSize(){return _outputBufferSize;};
size_t getOutputLen(){return _output_len;};
PacketShared::STATUS setOutputBufferIndex(int new_index);
byte getOutputFlags(){return _output_flags;};
void setOutputToAddress(uint32_t addr){_output_to_address = addr;};
uint32_t getOutputToAddress(){return _output_to_address;};
void flagOutputAsQuery(){_output_flags|=PacketShared::OPFLAG_IS_QUERY;};
void flagOutputAppendSendTimestamp(){_output_flags|=PacketShared::OPFLAG_APPEND_SEND_TIMESTAMP;};
bool outputIsQuery(){return (bool)_output_flags&PacketShared::OPFLAG_IS_QUERY;};
PacketShared::STATUS enqueueOutputBuffer(PacketQueue& pq);
PacketShared::STATUS dequeueOutputBuffer(PacketQueue& pq);
PacketShared::STATUS requeueOutputBuffer(PacketQueue& pq);
PacketShared::STATUS moveOutputBufferIndex(int n);
void resetOutputBuffer();
//unpacking chars and bytes
PacketShared::STATUS unpack_byte(byte& varByRef);
PacketShared::STATUS unpack_byte_array(byte* buffer, size_t len);
PacketShared::STATUS unpack_char(char& varByRef);
PacketShared::STATUS unpack_char_array(char* buffer, size_t len);
//unpacking stdint types
PacketShared::STATUS unpack_int8( int8_t& varByRef);
PacketShared::STATUS unpack_uint8( uint8_t& varByRef);
PacketShared::STATUS unpack_int16( int16_t& varByRef);
PacketShared::STATUS unpack_uint16(uint16_t& varByRef);
PacketShared::STATUS unpack_int32( int32_t& varByRef);
PacketShared::STATUS unpack_uint32(uint32_t& varByRef);
PacketShared::STATUS unpack_int64( int64_t& varByRef);
PacketShared::STATUS unpack_uint64(uint64_t& varByRef);
//unpacking floating point types
PacketShared::STATUS unpack_float( float& varByRef);
PacketShared::STATUS unpack_double( double& varByRef);
PacketShared::STATUS unpack_float32( float32_t& varByRef);
PacketShared::STATUS unpack_float64( float64_t& varByRef);
//Methods for constructing an output
PacketShared::STATUS setupOutputCommandByName(const char* name);
PacketShared::STATUS setupOutputCommand(CommandInfo command);
//packing chars and bytes
PacketShared::STATUS pack_byte(byte value);
PacketShared::STATUS pack_byte_array(byte* buffer, size_t len);
PacketShared::STATUS pack_char(char value);
PacketShared::STATUS pack_char_array(char* buffer, size_t len);
//packing stdint types
PacketShared::STATUS pack_int8( int8_t value);
PacketShared::STATUS pack_uint8( uint8_t value);
PacketShared::STATUS pack_int16( int16_t value);
PacketShared::STATUS pack_uint16(uint16_t value);
PacketShared::STATUS pack_int32( int32_t value);
PacketShared::STATUS pack_uint32(uint32_t value);
PacketShared::STATUS pack_int64( int64_t value);
PacketShared::STATUS pack_uint64(uint64_t value);
//packing floating point types
PacketShared::STATUS pack_float( float value);
PacketShared::STATUS pack_double( double value);
PacketShared::STATUS pack_float32( float32_t value);
PacketShared::STATUS pack_float64( float64_t value);
private:
//helper methods
void allocateInputBuffer(size_t len);
void allocateOutputBuffer(size_t len);
//data members
CommandInfo *_commandList; //array to hold command entries
CommandInfo _current_command; //command ready to dispatch
CommandInfo _default_command; //called when a packet's Type ID is not recognized
size_t _commandCount;
size_t _maxCommands;
//track state of input buffer
byte* _input_buffer; //this will be a fixed buffer location
size_t _inputBufferSize;
volatile size_t _input_index;
volatile size_t _input_len;
volatile byte _input_flags;
volatile uint32_t _recv_timestamp_micros;
struct InputProperties _input_properties;
//track state of output buffer
byte* _output_buffer; //this will be a fixed buffer location
size_t _outputBufferSize;
volatile size_t _output_index;
volatile size_t _output_len;
volatile byte _output_flags;
volatile uint32_t _output_to_address;
volatile uint32_t _send_timestamp_micros;
//cached callbacks
bool (*_send_callback)(PacketCommand& this_pCmd);
void (*_send_nonblocking_callback)(PacketCommand& this_pCmd);
void (*_send_buffered_callback)(PacketCommand& this_pCmd);
bool (*_recv_callback)(PacketCommand& this_pCmd);
void (*_reply_send_callback)(PacketCommand& this_pCmd);
bool (*_reply_recv_callback)(PacketCommand& this_pCmd);
};
#endif //PACKETCOMMAND_H