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 license@arduino.cc.
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