-
Notifications
You must be signed in to change notification settings - Fork 11
/
Sim900.h
235 lines (194 loc) · 6.83 KB
/
Sim900.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
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
/*
Sim900 is an Arduino library for working with the Sim900 GRPS Shield
Copyright (C) 2012 Nigel Bajema
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __SIM_900_H__
#define __SIM_900_H__
#define NULL 0
#define GET 0
#define POST 1
#define HEAD 2
#ifndef SIM900_POWERUP_THRESHOLD
#define SIM900_POWERUP_THRESHOLD 100
#endif
#ifndef SIM900_HTTP_TIMEOUT
#define SIM900_HTTP_TIMEOUT 100000
#endif
#define SIM900_ERROR_LIST_TERMINATOR 1
#define SIM900_ERROR_NO_ERROR 0
#define SIM900_ERROR_COULD_NOT_AQUIRE_LOCK -1
#define SIM900_ERROR_MODEM_ERROR -10
#define SIM900_ERROR_TIMEOUT -20
#define SIM900_ERROR_DATA_NOT_READY -30
#define SIM900_ERROR_MAX_POST_DATA_SIZE_EXCEEDED -40
#define SIM900_ERROR_READ_LIMIT_EXCEEDED -41
#define SIM900_ERROR_INVALID_CID_VALUE -50
#define SIM900_ERROR_CHARACTER_LIMIT_EXCEEDED -51
#define SIM900_ERROR_INVALID_CONNECTION_TYPE -52
#define SIM900_ERROR_INVALID_CONNECTION_RATE -53
#define SIM900_ERROR_INVALID_HTTP_TIMEOUT -54
#define SIM900_MAX_POST_DATA_V1 318976
#define SIM900_MAX_POST_DATA_V2 102400
#define SIM900_CONNECTION_INIT = 2;
#define SIM900_MAX_CONNECTION_SETTING_CHARACTERS 50
#include <Stream.h>
//#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
//#else
//#include "WProgram.h"
//#endif
#include <SoftwareSerial.h>
static bool SIM900_DEBUG_OUTPUT = false;
static Stream* SIM900_DEBUG_OUTPUT_STREAM = &Serial;
static unsigned long SIM900_INPUT_TIMEOUT = 60000l;
//According to http://www.mt-system.ru/sites/default/files/docs/simcom/docs/sim900/sim900_at_command_manual_v1.06.pdf
//There are multiple varients of the Sim900 modules, which affect things
//like the SIM900_MAX_POST_DATA size.
enum MODEM_VARIANT
{
VARIANT_1,
VARIANT_2
} ;
struct CONN
{
int cid; // Bearer profile identifier.
char* contype; // Valid Options: GPRS, CSD.
char* apn; // Provided by telco. Sometimes preprogrammed into the SIM card.
char* user; // Username, MAX 50 Characters.
char* pwd; // Password, MAX 50 Charcters.
char* phone; // Phone number for CSD call.
char* rate; // CSD connection rate.
CONN() : cid(-1), contype(NULL), apn(NULL), user(NULL), pwd(NULL), phone(NULL), rate(NULL) {}
};
struct error_message
{
int code;
char* message;
};
static error_message messages[] =
{
{SIM900_ERROR_NO_ERROR, "No Error"},
{SIM900_ERROR_COULD_NOT_AQUIRE_LOCK, "Only one connection at a time can use the modem."},
{SIM900_ERROR_MODEM_ERROR, "Modem Error"},
{SIM900_ERROR_TIMEOUT, "Timed out waiting for modem response."},
{SIM900_ERROR_DATA_NOT_READY, "init_retrieve needs to be called before data can be read."},
{SIM900_ERROR_MAX_POST_DATA_SIZE_EXCEEDED, "The maximum post data size was exceeded."},
{SIM900_ERROR_READ_LIMIT_EXCEEDED, "The read limit was exceeded."},
{SIM900_ERROR_INVALID_CID_VALUE, "Invalid Bearer profile Identifier"},
{SIM900_ERROR_CHARACTER_LIMIT_EXCEEDED, "The Maximum character limit was exceeded"},
{SIM900_ERROR_INVALID_CONNECTION_TYPE, "The specified connection type is not valid."},
{SIM900_ERROR_INVALID_CONNECTION_RATE, "The specified connection rate is not valid."},
{SIM900_ERROR_INVALID_HTTP_TIMEOUT, "The HTTP Timeout value must be between 30 and 1000 seconds."},
//This needs to be the last element or things will go badly wrong.
{SIM900_ERROR_LIST_TERMINATOR, NULL}
};
static const char *VALID_CONNECTION_TYPES[] = {
"GPRS",
"CSD",
NULL
};
static const int VALID_CONNECTION_SPEEDS[] =
{
2400,
4800,
9600,
14400,
NULL
};
bool is_valid_connection_type(char* to_check);
bool is_valid_connection_rate(char* to_check);
void set_sim900_debug_mode(bool mode);
void set_sim900_debug_stream(Stream* stream);
void set_sim900_input_timeout(unsigned long timeout);
char* get_error_message(int error_code);
class GPRSHTTP;
class Sim900
{
private:
Stream* _serial;
SoftwareSerial* _ser;
int _error_condition;
int _powerPin;
int _statusPin;
int _lock;
enum MODEM_VARIANT varient;
uint32_t max_http_post_size;
bool lock();
bool unlock();
bool dropEOL();
int waitFor(char target[], bool dropLastEOL, String* data);
int waitFor(char target[], bool dropLastEOL, String* data, unsigned long timeout);
bool compare(char to_test[], char target[], int pos, int length, int test_len);
void powerToggle();
bool issueCommand(char command[], char ok[], bool dropLastEOL);
void dumpStream();
void set_error_condition(int error_value);
bool is_valid_connection_settings(CONN settings);
void handle_varient(MODEM_VARIANT varient);
public:
Sim900(SoftwareSerial* serial, int baud_rate, int powerPin, int statusPin, enum MODEM_VARIANT varient);
Sim900(HardwareSerial* serial, int baud_rate, int powerPin, int statusPin, enum MODEM_VARIANT varient);
MODEM_VARIANT get_varient();
uint32_t get_max_http_post_size();
bool getSignalQuality(int &strength, int &error_rate);
bool waitForSignal(int iterations, int wait_time);
bool isPoweredUp();
bool powerUp();
bool powerDown();
GPRSHTTP* createHTTPConnection(CONN settings, char URL[]);
/*bool startGPRS();
bool stopGPRS();*/
int get_error_condition();
friend class GPRSHTTP;
};
class GPRSHTTP : public Stream
{
private:
uint32_t sequence_bit_map;
Sim900* _sim;
int _error_condition;
int _cid;
char* url;
String _data;
uint32_t write_limit, write_count;
uint32_t read_limit, read_count;
bool initialized, _data_ready;
int isCGATT();
bool HTTPINIT(int retries, int _delay);
bool stopBearer(int retries, int _delay);
bool startBearer(int retries, int _delay);
void set_error_condition(int error_value);
public:
GPRSHTTP(Sim900* sim, int cid, char URL[]);
bool init(int timeout = 120);
bool setParam(char* param, String value);
bool setParam(char* param, char* value);
bool setParam(char* param, uint32_t value);
bool post_init(uint32_t content_length);
//If the response from the server does not have a Content-Length header
//then length will always be zero.
bool post(int &cid, int &HTTP_CODE, int32_t &length);
int init_retrieve();
int get_error_condition();
bool terminate();
size_t read(char* buf, int length);
size_t read(byte* buf, int length);
virtual size_t write(uint8_t byte);
virtual int read();
virtual int available();
virtual void flush();
virtual int peek();
using Print::write;
};
#endif