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.getTime ();
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,57 @@ 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
+ return State::Connected;
121
111
}
122
112
123
- /* *****************************************************************************
124
- * PRIVATE MEMBER FUNCTIONS
125
- ******************************************************************************/
113
+ ArduinoIoTCloudLPWAN::State ArduinoIoTCloudLPWAN::handle_Connected ()
114
+ {
115
+ if (!connected ())
116
+ {
117
+ DBG_ERROR (" ArduinoIoTCloudLPWAN::%s connection to gateway lost" , __FUNCTION__);
118
+ return State::ConnectPhy;
119
+ }
120
+
121
+ /* Check if a primitive property wrapper is locally changed. */
122
+ updateTimestampOnLocallyChangedProperties (_property_container);
123
+
124
+ /* Decode available data. */
125
+ if (_connection->available ())
126
+ decodePropertiesFromCloud ();
127
+
128
+ /* If properties need updating sent them to the cloud. */
129
+ sendPropertiesToCloud ();
130
+
131
+ return State::Connected;
132
+ }
133
+
134
+ void ArduinoIoTCloudLPWAN::decodePropertiesFromCloud ()
135
+ {
136
+ uint8_t lora_msg_buf[CBOR_LORA_MSG_MAX_SIZE];
137
+ size_t bytes_received;
138
+ for (bytes_received = 0 ;
139
+ _connection->available () && (bytes_received < CBOR_LORA_MSG_MAX_SIZE);
140
+ bytes_received++)
141
+ {
142
+ lora_msg_buf[bytes_received] = _connection->read ();
143
+ }
144
+ CBORDecoder::decode (_property_container, lora_msg_buf, bytes_received);
145
+ }
126
146
127
147
void ArduinoIoTCloudLPWAN::sendPropertiesToCloud ()
128
148
{
0 commit comments