1
+ /*
2
+ This file is part of ArduinoIoTCloud.
3
+
4
+ Copyright 2019 ARDUINO SA (http://www.arduino.cc/)
5
+
6
+ This software is released under the GNU General Public License version 3,
7
+ which covers the main part of arduino-cli.
8
+ The terms of this license can be found at:
9
+ https://www.gnu.org/licenses/gpl-3.0.en.html
10
+
11
+ You can be released from the requirements of the above licenses by purchasing
12
+ a commercial license. Buying such a license is mandatory if you want to modify or
13
+ otherwise use the software for commercial activities involving the Arduino
14
+ software without disclosing the source code of your own applications. To purchase
15
+ a commercial license, send an email to [email protected] .
16
+ */
17
+
18
+ /* *****************************************************************************
19
+ INCLUDE
20
+ ******************************************************************************/
21
+
22
+ /*
23
+ static int const DBG_NONE = -1;
24
+ static int const DBG_ERROR = 0;
25
+ static int const DBG_WARNING = 1;
26
+ static int const DBG_INFO = 2;
27
+ static int const DBG_DEBUG = 3;
28
+ static int const DBG_VERBOSE = 4;
29
+ */
30
+
31
+ #include " Arduino_GSMConnectionHandler.h"
32
+
33
+ #ifdef BOARD_HAS_GSM /* Only compile if this is a board with GSM */
34
+
35
+ /* *****************************************************************************
36
+ CONSTANTS
37
+ ******************************************************************************/
38
+
39
+ static const unsigned long NETWORK_CONNECTION_INTERVAL = 30000 ;
40
+
41
+ /* *****************************************************************************
42
+ CTOR/DTOR
43
+ ******************************************************************************/
44
+
45
+ GSMConnectionHandler::GSMConnectionHandler (const char *pin, const char *apn, const char *login, const char *pass, bool _keepAlive) :
46
+ pin(pin),
47
+ apn(apn),
48
+ login(login),
49
+ pass(pass),
50
+ lastConnectionTickTime(millis()),
51
+ connectionTickTimeInterval(CHECK_INTERVAL_IDLE),
52
+ keepAlive(_keepAlive),
53
+ _on_connect_event_callback(NULL ),
54
+ _on_disconnect_event_callback(NULL ),
55
+ _on_error_event_callback(NULL ) {
56
+ }
57
+
58
+ /* *****************************************************************************
59
+ PUBLIC MEMBER FUNCTIONS
60
+ ******************************************************************************/
61
+
62
+ void GSMConnectionHandler::init () {
63
+ char msgBuffer[120 ];
64
+ if (gsmAccess.begin (pin) == GSM_READY) {
65
+ Debug.print (DBG_INFO, " SIM card ok" );
66
+ gsmAccess.setTimeout (CHECK_INTERVAL_RETRYING);
67
+ changeConnectionState (NetworkConnectionState::CONNECTING);
68
+ } else {
69
+ Debug.print (DBG_ERROR, " SIM not present or wrong PIN" );
70
+ while (1 );
71
+ }
72
+ }
73
+
74
+ void GSMConnectionHandler::addCallback (NetworkConnectionEvent const event, OnNetworkEventCallback callback) {
75
+ switch (event) {
76
+ case NetworkConnectionEvent::CONNECTED: _on_connect_event_callback = callback; break ;
77
+ case NetworkConnectionEvent::DISCONNECTED: _on_disconnect_event_callback = callback; break ;
78
+ case NetworkConnectionEvent::ERROR: _on_error_event_callback = callback; break ;
79
+ case NetworkConnectionEvent::INIT: ; break ;
80
+ case NetworkConnectionEvent::CONNECTING: ; break ;
81
+ case NetworkConnectionEvent::DISCONNECTING: ; break ;
82
+ case NetworkConnectionEvent::CLOSED: ; break ;
83
+ }
84
+ }
85
+
86
+ void GSMConnectionHandler::addConnectCallback (OnNetworkEventCallback callback) {
87
+ _on_connect_event_callback = callback;
88
+ }
89
+ void GSMConnectionHandler::addDisconnectCallback (OnNetworkEventCallback callback) {
90
+ _on_disconnect_event_callback = callback;
91
+ }
92
+ void GSMConnectionHandler::addErrorCallback (OnNetworkEventCallback callback) {
93
+ _on_error_event_callback = callback;
94
+ }
95
+
96
+ void GSMConnectionHandler::execNetworkEventCallback (OnNetworkEventCallback & callback, void * callback_arg) {
97
+ if (callback) {
98
+ (*callback)(callback_arg);
99
+ }
100
+ }
101
+
102
+ unsigned long GSMConnectionHandler::getTime () {
103
+ return gsmAccess.getTime ();
104
+ }
105
+
106
+ void GSMConnectionHandler::update () {
107
+ unsigned long const now = millis ();
108
+ int gsmAccessAlive;
109
+ if (now - lastConnectionTickTime > connectionTickTimeInterval) {
110
+ switch (netConnectionState) {
111
+ case NetworkConnectionState::INIT: {
112
+ init ();
113
+ }
114
+ break ;
115
+ case NetworkConnectionState::CONNECTING: {
116
+ // NOTE: Blocking Call when 4th parameter == true
117
+ GSM3_NetworkStatus_t networkStatus;
118
+ networkStatus = gprs.attachGPRS (apn, login, pass, true );
119
+ Debug.print (DBG_DEBUG, " GPRS.attachGPRS(): %d" , networkStatus);
120
+ if (networkStatus == GSM3_NetworkStatus_t::ERROR) {
121
+ // NO FURTHER ACTION WILL FOLLOW THIS
122
+ changeConnectionState (NetworkConnectionState::ERROR);
123
+ return ;
124
+ }
125
+ Debug.print (DBG_INFO, " Sending PING to outer space..." );
126
+ int pingResult;
127
+ pingResult = gprs.ping (" time.arduino.cc" );
128
+ Debug.print (DBG_INFO, " GSM.ping(): %d" , pingResult);
129
+ if (pingResult < 0 ) {
130
+ Debug.print (DBG_ERROR, " PING failed" );
131
+ Debug.print (DBG_INFO, " Retrying in \" %d\" milliseconds" , connectionTickTimeInterval);
132
+ return ;
133
+ } else {
134
+ Debug.print (DBG_INFO, " Connected to GPRS Network" );
135
+ changeConnectionState (NetworkConnectionState::CONNECTED);
136
+ return ;
137
+ }
138
+ }
139
+ break ;
140
+ case NetworkConnectionState::CONNECTED: {
141
+ gsmAccessAlive = gsmAccess.isAccessAlive ();
142
+ Debug.print (DBG_VERBOSE, " GPRS.isAccessAlive(): %d" , gsmAccessAlive);
143
+ if (gsmAccessAlive != 1 ) {
144
+ changeConnectionState (NetworkConnectionState::DISCONNECTED);
145
+ return ;
146
+ }
147
+ Debug.print (DBG_VERBOSE, " Connected to Cellular Network" );
148
+ }
149
+ break ;
150
+ case NetworkConnectionState::DISCONNECTED: {
151
+ // gprs.detachGPRS();
152
+ if (keepAlive) {
153
+ Debug.print (DBG_VERBOSE, " keep alive > INIT" );
154
+ changeConnectionState (NetworkConnectionState::INIT);
155
+ } else {
156
+ changeConnectionState (NetworkConnectionState::CLOSED);
157
+ }
158
+ // changeConnectionState(NetworkConnectionState::CONNECTING);
159
+ }
160
+ break ;
161
+ }
162
+ lastConnectionTickTime = now;
163
+ }
164
+ }
165
+
166
+ /* *****************************************************************************
167
+ PRIVATE MEMBER FUNCTIONS
168
+ ******************************************************************************/
169
+
170
+ void GSMConnectionHandler::changeConnectionState (NetworkConnectionState _newState) {
171
+ int newInterval = CHECK_INTERVAL_IDLE;
172
+ switch (_newState) {
173
+ case NetworkConnectionState::INIT: {
174
+ newInterval = CHECK_INTERVAL_INIT;
175
+ }
176
+ break ;
177
+ case NetworkConnectionState::CONNECTING: {
178
+ Debug.print (DBG_INFO, " Connecting to Cellular Network" );
179
+ newInterval = CHECK_INTERVAL_CONNECTING;
180
+ }
181
+ break ;
182
+ case NetworkConnectionState::CONNECTED: {
183
+ execNetworkEventCallback (_on_connect_event_callback, 0 );
184
+ newInterval = CHECK_INTERVAL_CONNECTED;
185
+ }
186
+ break ;
187
+ case NetworkConnectionState::GETTIME: {
188
+ }
189
+ break ;
190
+ case NetworkConnectionState::DISCONNECTING: {
191
+ Debug.print (DBG_VERBOSE, " Disconnecting from Cellular Network" );
192
+ gsmAccess.shutdown ();
193
+ }
194
+ case NetworkConnectionState::DISCONNECTED: {
195
+ if (netConnectionState == NetworkConnectionState::CONNECTED) {
196
+ execNetworkEventCallback (_on_disconnect_event_callback, 0 );
197
+ Debug.print (DBG_ERROR, " Disconnected from Cellular Network" );
198
+ Debug.print (DBG_ERROR, " Attempting reconnection" );
199
+ if (keepAlive) {
200
+ Debug.print (DBG_ERROR, " Attempting reconnection" );
201
+ }
202
+ }
203
+ newInterval = CHECK_INTERVAL_DISCONNECTED;
204
+ }
205
+ break ;
206
+ case NetworkConnectionState::ERROR: {
207
+ execNetworkEventCallback (_on_error_event_callback, 0 );
208
+ Debug.print (DBG_ERROR, " GPRS attach failed\n\r Make sure the antenna is connected and reset your board." );
209
+ }
210
+ break ;
211
+ }
212
+ connectionTickTimeInterval = newInterval;
213
+ lastConnectionTickTime = millis ();
214
+ netConnectionState = _newState;
215
+ }
216
+
217
+
218
+ void GSMConnectionHandler::connect () {
219
+ if (netConnectionState == NetworkConnectionState::INIT || netConnectionState == NetworkConnectionState::CONNECTING){
220
+ return ;
221
+ }
222
+ keepAlive = true ;
223
+ changeConnectionState (NetworkConnectionState::INIT);
224
+
225
+ }
226
+ void GSMConnectionHandler::disconnect () {
227
+ // WiFi.end();
228
+
229
+ changeConnectionState (NetworkConnectionState::DISCONNECTING);
230
+ keepAlive = false ;
231
+ }
232
+
233
+ #endif /* #ifdef BOARD_HAS_GSM */
0 commit comments