-
Notifications
You must be signed in to change notification settings - Fork 14
/
SIMComAT.h
180 lines (156 loc) · 5.16 KB
/
SIMComAT.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
#pragma once
#include <Arduino.h>
#include <ArduinoLog.h>
#include "SIMComAT.Common.h"
#define _SIM808_DEBUG _DEBUG
#if _SIM808_DEBUG
#define SIM808_PRINT(...) _debug.verbose(__VA_ARGS__)
#define SIM808_PRINT_CHAR(x) Serial.print((char)x)
#define SIM808_PRINT_P(fmt, ...) _debug.verbose(S_F(fmt "\n"), __VA_ARGS__)
#define SIM808_PRINT_SIMPLE_P(fmt) _debug.verbose(S_F(fmt "\n"))
#define RECEIVEARROW _debug.verbose(S_F("<--"))
#define SENDARROW _debug.verbose(S_F("\n-->"))
#else
#define SIM808_PRINT(...)
#define SIM808_PRINT_CHAR(x)
#define SIM808_PRINT_P(x, ...)
#define SIM808_PRINT_SIMPLE_P(x)
#define RECEIVEARROW
#define SENDARROW
#endif // _DEBUG
#if SIZE_MAX > UINT16_MAX
#define NEED_SIZE_T_OVERLOADS
#endif
#define BUFFER_SIZE 64
#define SIMCOMAT_DEFAULT_TIMEOUT 1000
class SIMComAT : public Stream
{
private:
protected:
Stream* _port;
Logging _output;
#if _SIM808_DEBUG
Logging _debug;
#endif
char replyBuffer[BUFFER_SIZE];
template<typename T> void writeStream(T last)
{
print(last);
}
template<typename T, typename... Args> void writeStream(T head, Args... tail)
{
print(head);
writeStream(tail...);
}
template<typename... Args> void sendAT(Args... cmd)
{
SENDARROW;
writeStream(TO_F(TOKEN_AT), cmd..., TO_F(TOKEN_NL));
}
template<typename T, typename... Args> void sendFormatAT(T format, Args... args)
{
SENDARROW;
writeStream(TO_F(TOKEN_AT));
_output.verbose(format, args...);
writeStream(TO_F(TOKEN_NL));
}
/**
* Read and discard all content already waiting to be parsed.
*/
void flushInput();
/**
* Read at max size available chars into buffer until either the timeout is exhausted or
* the stop character is encountered. timeout and char are optional
*
*/
size_t readNext(char * buffer, size_t size, uint16_t * timeout = NULL, char stop = 0);
int8_t waitResponse(
ATConstStr s1 = TO_F(TOKEN_OK),
ATConstStr s2 = TO_F(TOKEN_ERROR),
ATConstStr s3 = NULL,
ATConstStr s4 = NULL) {
return waitResponse(SIMCOMAT_DEFAULT_TIMEOUT, s1, s2, s3, s4);
};
int8_t waitResponse(uint16_t timeout,
ATConstStr s1 = TO_F(TOKEN_OK),
ATConstStr s2 = TO_F(TOKEN_ERROR),
ATConstStr s3 = NULL,
ATConstStr s4 = NULL);
/**
* Read the current response line and copy it in response. Start at replyBuffer + shift
*/
size_t copyCurrentLine(char *dst, size_t dstSize, uint16_t shift = 0);
size_t safeCopy(const char *src, char *dst, size_t dstSize);
/**
* Find and return a pointer to the nth field of a string.
*/
char* find(const char* str, char divider, uint8_t index);
/**
* Parse the nth field of a string as a uint8_t.
*/
bool parse(const char* str, char divider, uint8_t index, uint8_t* result);
/**
* Parse the nth field of a string as a int8_t.
*/
bool parse(const char* str, char divider, uint8_t index, int8_t* result);
/**
* Parse the nth field of a string as a uint16_t.
*/
bool parse(const char* str, char divider, uint8_t index, uint16_t* result);
#if defined(NEED_SIZE_T_OVERLOADS)
/**
* Parse the nth field of a string as a size_t.
*/
bool parse(const char* str, char divider, uint8_t index, size_t* result);
#endif
/**
* Parse the nth field of a string as a int16_t.
*/
bool parse(const char* str, char divider, uint8_t index, int16_t* result);
/**
* Parse the nth field of a string as a float.
*/
bool parse(const char* str, char divider, uint8_t index, float* result);
/**
* Parse the nth field of the reply buffer as a uint8_t.
*/
bool parseReply(char divider, uint8_t index, uint8_t* result) { return parse(replyBuffer, divider, index, result); }
/**
* Parse the nth field of the reply buffer as a int8_t.
*/
bool parseReply(char divider, uint8_t index, int8_t* result) { return parse(replyBuffer, divider, index, result); }
/**
* Parse the nth field of the reply buffer as a uint16_t.
*/
bool parseReply(char divider, uint8_t index, uint16_t* result) { return parse(replyBuffer, divider, index, result); }
#if defined(NEED_SIZE_T_OVERLOADS)
/**
* Parse the nth field of the reply buffer as a size_t.
*/
bool parseReply(char divider, uint8_t index, size_t* result) { return parse(replyBuffer, divider, index, result); }
#endif
/**
* Parse the nth field of the reply buffer as a int16_t.
*/
bool parseReply(char divider, uint8_t index, int16_t* result) { return parse(replyBuffer, divider, index, result); }
/**
* Parse the nth field of the reply buffer as a float.
*/
bool parseReply(char divider, uint8_t index, float* result) { return parse(replyBuffer, divider, index, result); }
/**
* Perform the minmum commands needed to get the device communication up and running.
*/
virtual void init()=0;
public:
/**
* Begin communicating with the device.
*/
void begin(Stream& port);
#pragma region Stream implementation
int available() { return _port->available(); }
size_t write(uint8_t x) { SIM808_PRINT_CHAR(x); return _port->write(x); }
int read() { return _port->read(); }
int peek() { return _port->peek(); }
void flush() { return _port->flush(); }
#pragma endregion
};