33
33
34
34
static size_t const CBOR_LORA_MSG_MAX_SIZE = 255 ;
35
35
36
+ /* *****************************************************************************
37
+ LOCAL MODULE FUNCTIONS
38
+ ******************************************************************************/
39
+
40
+ extern " C" unsigned long getTime ()
41
+ {
42
+ return ArduinoCloud.getInternalTime ();
43
+ }
44
+
36
45
/* *****************************************************************************
37
46
CTOR/DTOR
38
47
******************************************************************************/
39
48
40
49
ArduinoIoTCloudLPWAN::ArduinoIoTCloudLPWAN ()
41
- : _retryEnable{false }
50
+ : _state{State::ConnectPhy}
51
+ , _retryEnable{false }
42
52
, _maxNumRetry{5 }
43
53
, _intervalRetry{1000 }
44
54
{
@@ -58,45 +68,21 @@ int ArduinoIoTCloudLPWAN::begin(ConnectionHandler& connection, bool retry)
58
68
{
59
69
_connection = &connection;
60
70
_retryEnable = retry;
71
+ _time_service.begin (nullptr );
61
72
return 1 ;
62
73
}
63
74
64
75
void ArduinoIoTCloudLPWAN::update ()
65
76
{
66
- // Check if a primitive property wrapper is locally changed
67
- updateTimestampOnLocallyChangedProperties (_property_container);
68
-
69
- ArduinoIoTConnectionStatus next_iot_status = _iot_status;
70
-
71
- /* Since we do not have a direct connection to the Arduino IoT Cloud servers
72
- * there is no such thing is a 'cloud connection state' since the LoRa
73
- * board connection state to the gateway is all the information we have.
74
- */
75
- NetworkConnectionState const net_con_state = checkPhyConnection ();
76
- if (net_con_state == NetworkConnectionState::CONNECTED) { next_iot_status = ArduinoIoTConnectionStatus::CONNECTED; execCloudEventCallback (ArduinoIoTCloudEvent::CONNECT); }
77
- else if (net_con_state == NetworkConnectionState::CONNECTING) { next_iot_status = ArduinoIoTConnectionStatus::CONNECTING; }
78
- else if (net_con_state == NetworkConnectionState::DISCONNECTED) { next_iot_status = ArduinoIoTConnectionStatus::DISCONNECTED; execCloudEventCallback (ArduinoIoTCloudEvent::DISCONNECT); }
79
-
80
- if (next_iot_status != _iot_status)
77
+ /* Run through the state machine. */
78
+ State next_state = _state;
79
+ switch (_state)
81
80
{
82
- printConnectionStatus (next_iot_status);
83
- _iot_status = next_iot_status;
84
- }
85
-
86
- if (net_con_state != NetworkConnectionState::CONNECTED) return ;
87
-
88
- if (_connection->available ()) {
89
- uint8_t msgBuf[CBOR_LORA_MSG_MAX_SIZE];
90
- uint8_t i = 0 ;
91
- while (_connection->available ()) {
92
- msgBuf[i++] = _connection->read ();
93
- }
94
-
95
- CBORDecoder::decode (_property_container, msgBuf, sizeof (msgBuf));
81
+ case State::ConnectPhy: next_state = handle_ConnectPhy (); break ;
82
+ case State::SyncTime: next_state = handle_SyncTime (); break ;
83
+ case State::Connected: next_state = handle_Connected (); break ;
96
84
}
97
-
98
- sendPropertiesToCloud ();
99
- execCloudEventCallback (ArduinoIoTCloudEvent::SYNC);
85
+ _state = next_state;
100
86
}
101
87
102
88
void ArduinoIoTCloudLPWAN::printDebugInfo ()
@@ -106,23 +92,58 @@ void ArduinoIoTCloudLPWAN::printDebugInfo()
106
92
}
107
93
108
94
/* *****************************************************************************
109
- * PROTECTED MEMBER FUNCTIONS
95
+ * PRIVATE MEMBER FUNCTIONS
110
96
******************************************************************************/
111
97
112
- int ArduinoIoTCloudLPWAN::connect ()
98
+ ArduinoIoTCloudLPWAN::State ArduinoIoTCloudLPWAN::handle_ConnectPhy ()
113
99
{
114
- _connection->connect ();
115
- return 1 ;
100
+ if (_connection->check () == NetworkConnectionState::CONNECTED)
101
+ return State::SyncTime;
102
+ else
103
+ return State::ConnectPhy;
116
104
}
117
105
118
- void ArduinoIoTCloudLPWAN::disconnect ()
106
+ ArduinoIoTCloudLPWAN::State ArduinoIoTCloudLPWAN::handle_SyncTime ()
119
107
{
120
- _connection->disconnect ();
108
+ unsigned long const internal_posix_time = _time_service.getTime ();
109
+ DBG_VERBOSE (" ArduinoIoTCloudLPWAN::%s internal clock configured to posix timestamp %d" , __FUNCTION__, internal_posix_time);
110
+ DBG_INFO (" Connected to Arduino IoT Cloud" );
111
+ return State::Connected;
121
112
}
122
113
123
- /* *****************************************************************************
124
- * PRIVATE MEMBER FUNCTIONS
125
- ******************************************************************************/
114
+ ArduinoIoTCloudLPWAN::State ArduinoIoTCloudLPWAN::handle_Connected ()
115
+ {
116
+ if (!connected ())
117
+ {
118
+ DBG_ERROR (" ArduinoIoTCloudLPWAN::%s connection to gateway lost" , __FUNCTION__);
119
+ return State::ConnectPhy;
120
+ }
121
+
122
+ /* Check if a primitive property wrapper is locally changed. */
123
+ updateTimestampOnLocallyChangedProperties (_property_container);
124
+
125
+ /* Decode available data. */
126
+ if (_connection->available ())
127
+ decodePropertiesFromCloud ();
128
+
129
+ /* If properties need updating sent them to the cloud. */
130
+ sendPropertiesToCloud ();
131
+
132
+ return State::Connected;
133
+ }
134
+
135
+ void ArduinoIoTCloudLPWAN::decodePropertiesFromCloud ()
136
+ {
137
+ uint8_t lora_msg_buf[CBOR_LORA_MSG_MAX_SIZE];
138
+ size_t bytes_received;
139
+ for (bytes_received = 0 ;
140
+ _connection->available () && (bytes_received < CBOR_LORA_MSG_MAX_SIZE);
141
+ bytes_received++)
142
+ {
143
+ lora_msg_buf[bytes_received] = _connection->read ();
144
+ }
145
+ CBORDecoder::decode (_property_container, lora_msg_buf, bytes_received);
146
+ }
126
147
127
148
void ArduinoIoTCloudLPWAN::sendPropertiesToCloud ()
128
149
{
@@ -138,7 +159,8 @@ int ArduinoIoTCloudLPWAN::writeProperties(const byte data[], int length)
138
159
{
139
160
int retcode = _connection->write (data, length);
140
161
int i = 0 ;
141
- while (_retryEnable && retcode < 0 && i < _maxNumRetry) {
162
+ while (_retryEnable && retcode < 0 && i < _maxNumRetry)
163
+ {
142
164
delay (_intervalRetry);
143
165
retcode = _connection->write (data, length);
144
166
i++;
0 commit comments